mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-25 21:54:14 -08:00
Merge pull request #13964 from spencerrlongg/refactor/store_asset_form_request
Tests For API Asset Store + Refactor For Auto Increment & Form Requests
This commit is contained in:
commit
cce9540316
|
@ -3,15 +3,16 @@
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Events\CheckoutableCheckedIn;
|
use App\Events\CheckoutableCheckedIn;
|
||||||
|
use App\Http\Requests\StoreAssetRequest;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\AssetCheckoutRequest;
|
use App\Http\Requests\AssetCheckoutRequest;
|
||||||
use App\Http\Transformers\AssetsTransformer;
|
use App\Http\Transformers\AssetsTransformer;
|
||||||
use App\Http\Transformers\DepreciationReportTransformer;
|
|
||||||
use App\Http\Transformers\LicensesTransformer;
|
use App\Http\Transformers\LicensesTransformer;
|
||||||
use App\Http\Transformers\SelectlistTransformer;
|
use App\Http\Transformers\SelectlistTransformer;
|
||||||
use App\Models\Actionlog;
|
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\AssetModel;
|
use App\Models\AssetModel;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
|
@ -20,11 +21,12 @@ use App\Models\License;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Auth;
|
use \Illuminate\Support\Facades\Auth;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use DB;
|
use DB;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Requests\ImageUploadRequest;
|
use App\Http\Requests\ImageUploadRequest;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Input;
|
use Input;
|
||||||
use Paginator;
|
use Paginator;
|
||||||
use Slack;
|
use Slack;
|
||||||
|
@ -531,37 +533,14 @@ class AssetsController extends Controller
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @param \App\Http\Requests\ImageUploadRequest $request
|
* @param \App\Http\Requests\ImageUploadRequest $request
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*/
|
*/
|
||||||
public function store(ImageUploadRequest $request)
|
public function store(StoreAssetRequest $request): JsonResponse
|
||||||
{
|
{
|
||||||
$this->authorize('create', Asset::class);
|
|
||||||
|
|
||||||
$asset = new Asset();
|
$asset = new Asset();
|
||||||
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
||||||
|
|
||||||
$asset->name = $request->get('name');
|
$asset->fill($request->validated());
|
||||||
$asset->serial = $request->get('serial');
|
|
||||||
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id'));
|
|
||||||
$asset->model_id = $request->get('model_id');
|
|
||||||
$asset->order_number = $request->get('order_number');
|
|
||||||
$asset->notes = $request->get('notes');
|
|
||||||
$asset->asset_tag = $request->get('asset_tag', Asset::autoincrement_asset());
|
|
||||||
$asset->user_id = Auth::id();
|
$asset->user_id = Auth::id();
|
||||||
$asset->archived = '0';
|
|
||||||
$asset->physical = '1';
|
|
||||||
$asset->depreciate = '0';
|
|
||||||
$asset->status_id = $request->get('status_id', 0);
|
|
||||||
$asset->warranty_months = $request->get('warranty_months', null);
|
|
||||||
$asset->purchase_cost = $request->get('purchase_cost');
|
|
||||||
$asset->asset_eol_date = $request->get('asset_eol_date', $asset->present()->eol_date());
|
|
||||||
$asset->purchase_date = $request->get('purchase_date', null);
|
|
||||||
$asset->assigned_to = $request->get('assigned_to', null);
|
|
||||||
$asset->supplier_id = $request->get('supplier_id');
|
|
||||||
$asset->requestable = $request->get('requestable', 0);
|
|
||||||
$asset->rtd_location_id = $request->get('rtd_location_id', null);
|
|
||||||
$asset->location_id = $request->get('rtd_location_id', null);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this is here just legacy reasons. Api\AssetController
|
* this is here just legacy reasons. Api\AssetController
|
||||||
|
@ -586,22 +565,22 @@ class AssetsController extends Controller
|
||||||
|
|
||||||
// If input value is null, use custom field's default value
|
// If input value is null, use custom field's default value
|
||||||
if ($field_val == null) {
|
if ($field_val == null) {
|
||||||
\Log::debug('Field value for '.$field->db_column.' is null');
|
Log::debug('Field value for '.$field->db_column.' is null');
|
||||||
$field_val = $field->defaultValue($request->get('model_id'));
|
$field_val = $field->defaultValue($request->get('model_id'));
|
||||||
\Log::debug('Use the default fieldset value of '.$field->defaultValue($request->get('model_id')));
|
Log::debug('Use the default fieldset value of '.$field->defaultValue($request->get('model_id')));
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the field is set to encrypted, make sure we encrypt the value
|
// if the field is set to encrypted, make sure we encrypt the value
|
||||||
if ($field->field_encrypted == '1') {
|
if ($field->field_encrypted == '1') {
|
||||||
\Log::debug('This model field is encrypted in this fieldset.');
|
Log::debug('This model field is encrypted in this fieldset.');
|
||||||
|
|
||||||
if (Gate::allows('admin')) {
|
if (Gate::allows('admin')) {
|
||||||
|
|
||||||
// If input value is null, use custom field's default value
|
// If input value is null, use custom field's default value
|
||||||
if (($field_val == null) && ($request->has('model_id') != '')) {
|
if (($field_val == null) && ($request->has('model_id') != '')) {
|
||||||
$field_val = \Crypt::encrypt($field->defaultValue($request->get('model_id')));
|
$field_val = Crypt::encrypt($field->defaultValue($request->get('model_id')));
|
||||||
} else {
|
} else {
|
||||||
$field_val = \Crypt::encrypt($request->input($field->db_column));
|
$field_val = Crypt::encrypt($request->input($field->db_column));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,9 +131,6 @@ class AssetsController extends Controller
|
||||||
$asset->order_number = $request->input('order_number');
|
$asset->order_number = $request->input('order_number');
|
||||||
$asset->notes = $request->input('notes');
|
$asset->notes = $request->input('notes');
|
||||||
$asset->user_id = Auth::id();
|
$asset->user_id = Auth::id();
|
||||||
$asset->archived = '0';
|
|
||||||
$asset->physical = '1';
|
|
||||||
$asset->depreciate = '0';
|
|
||||||
$asset->status_id = request('status_id');
|
$asset->status_id = request('status_id');
|
||||||
$asset->warranty_months = request('warranty_months', null);
|
$asset->warranty_months = request('warranty_months', null);
|
||||||
$asset->purchase_cost = request('purchase_cost');
|
$asset->purchase_cost = request('purchase_cost');
|
||||||
|
@ -365,7 +362,6 @@ class AssetsController extends Controller
|
||||||
$asset->order_number = $request->input('order_number');
|
$asset->order_number = $request->input('order_number');
|
||||||
$asset->asset_tag = $asset_tag[1];
|
$asset->asset_tag = $asset_tag[1];
|
||||||
$asset->notes = $request->input('notes');
|
$asset->notes = $request->input('notes');
|
||||||
$asset->physical = '1';
|
|
||||||
|
|
||||||
$asset = $request->handleImages($asset);
|
$asset = $request->handleImages($asset);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Http\Requests;
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use App\Models\Company;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
|
||||||
class StoreAssetRequest extends ImageUploadRequest
|
class StoreAssetRequest extends ImageUploadRequest
|
||||||
|
@ -20,7 +20,11 @@ class StoreAssetRequest extends ImageUploadRequest
|
||||||
|
|
||||||
public function prepareForValidation(): void
|
public function prepareForValidation(): void
|
||||||
{
|
{
|
||||||
//
|
$this->merge([
|
||||||
|
'asset_tag' => $this->asset_tag ?? Asset::autoincrement_asset(),
|
||||||
|
'company_id' => Company::getIdForCurrentUser($this->company_id),
|
||||||
|
'assigned_to' => $assigned_to ?? null,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -89,24 +89,27 @@ class Asset extends Depreciable
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'name' => 'max:255|nullable',
|
|
||||||
'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array',
|
'model_id' => 'required|integer|exists:models,id,deleted_at,NULL|not_array',
|
||||||
'status_id' => 'required|integer|exists:status_labels,id',
|
'status_id' => 'required|integer|exists:status_labels,id',
|
||||||
'company_id' => 'integer|nullable',
|
|
||||||
'warranty_months' => 'numeric|nullable|digits_between:0,240',
|
|
||||||
'physical' => 'numeric|max:1|nullable',
|
|
||||||
'last_checkout' => 'date_format:Y-m-d H:i:s|nullable',
|
|
||||||
'expected_checkin' => 'date|nullable',
|
|
||||||
'location_id' => 'exists:locations,id|nullable',
|
|
||||||
'rtd_location_id' => 'exists:locations,id|nullable',
|
|
||||||
'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array',
|
'asset_tag' => 'required|min:1|max:255|unique_undeleted:assets,asset_tag|not_array',
|
||||||
'purchase_date' => 'date|date_format:Y-m-d|nullable',
|
'name' => 'nullable|max:255',
|
||||||
'serial' => 'unique_undeleted:assets,serial|nullable',
|
'company_id' => 'nullable|integer|exists:companies,id',
|
||||||
'purchase_cost' => 'numeric|nullable|gte:0',
|
'warranty_months' => 'nullable|numeric|digits_between:0,240',
|
||||||
'supplier_id' => 'exists:suppliers,id|nullable',
|
'last_checkout' => 'nullable|date_format:Y-m-d H:i:s',
|
||||||
'asset_eol_date' => 'date|nullable',
|
'expected_checkin' => 'nullable|date',
|
||||||
'eol_explicit' => 'boolean|nullable',
|
'location_id' => 'nullable|exists:locations,id',
|
||||||
'byod' => 'boolean',
|
'rtd_location_id' => 'nullable|exists:locations,id',
|
||||||
|
'purchase_date' => 'nullable|date|date_format:Y-m-d',
|
||||||
|
'serial' => 'nullable|unique_undeleted:assets,serial',
|
||||||
|
'purchase_cost' => 'nullable|numeric|gte:0',
|
||||||
|
'supplier_id' => 'nullable|exists:suppliers,id',
|
||||||
|
'asset_eol_date' => 'nullable|date',
|
||||||
|
'eol_explicit' => 'nullable|boolean',
|
||||||
|
'byod' => 'nullable|boolean',
|
||||||
|
'order_number' => 'nullable|string|max:191',
|
||||||
|
'notes' => 'nullable|string|max:65535',
|
||||||
|
'assigned_to' => 'nullable|integer',
|
||||||
|
'requestable' => 'nullable|boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
@ -460,13 +463,22 @@ class Asset extends Depreciable
|
||||||
*
|
*
|
||||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||||
* @since [v4.0]
|
* @since [v4.0]
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
public function checkedOutToUser()
|
public function checkedOutToUser(): bool
|
||||||
{
|
{
|
||||||
return $this->assignedType() === self::USER;
|
return $this->assignedType() === self::USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkedOutToLocation(): bool
|
||||||
|
{
|
||||||
|
return $this->assignedType() === self::LOCATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkedOutToAsset(): bool
|
||||||
|
{
|
||||||
|
return $this->assignedType() === self::ASSET;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the target this asset is checked out to
|
* Get the target this asset is checked out to
|
||||||
*
|
*
|
||||||
|
@ -728,7 +740,7 @@ class Asset extends Depreciable
|
||||||
{
|
{
|
||||||
$days = (is_null($days)) ? 30 : $days;
|
$days = (is_null($days)) ? 30 : $days;
|
||||||
|
|
||||||
return self::where('archived', '=', '0')
|
return self::where('archived', '=', '0') // this can stay for right now, as `archived` defaults to 0 at the db level, but should probably be replaced with assetstatus->archived?
|
||||||
->whereNotNull('warranty_months')
|
->whereNotNull('warranty_months')
|
||||||
->whereNotNull('purchase_date')
|
->whereNotNull('purchase_date')
|
||||||
->whereNull('deleted_at')
|
->whereNull('deleted_at')
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AssetFactory extends Factory
|
||||||
'notes' => 'Created by DB seeder',
|
'notes' => 'Created by DB seeder',
|
||||||
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
|
'purchase_date' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get())->format('Y-m-d'),
|
||||||
'purchase_cost' => $this->faker->randomFloat(2, '299.99', '2999.99'),
|
'purchase_cost' => $this->faker->randomFloat(2, '299.99', '2999.99'),
|
||||||
'order_number' => $this->faker->numberBetween(1000000, 50000000),
|
'order_number' => (string) $this->faker->numberBetween(1000000, 50000000),
|
||||||
'supplier_id' => Supplier::factory(),
|
'supplier_id' => Supplier::factory(),
|
||||||
'requestable' => $this->faker->boolean(),
|
'requestable' => $this->faker->boolean(),
|
||||||
'assigned_to' => null,
|
'assigned_to' => null,
|
||||||
|
|
|
@ -2,7 +2,14 @@
|
||||||
|
|
||||||
namespace Tests\Feature\Api\Assets;
|
namespace Tests\Feature\Api\Assets;
|
||||||
|
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\AssetModel;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\Location;
|
||||||
|
use App\Models\Statuslabel;
|
||||||
|
use App\Models\Supplier;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Tests\Support\InteractsWithSettings;
|
use Tests\Support\InteractsWithSettings;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
@ -16,4 +23,406 @@ class AssetStoreTest extends TestCase
|
||||||
->postJson(route('api.assets.store'))
|
->postJson(route('api.assets.store'))
|
||||||
->assertForbidden();
|
->assertForbidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAllAssetAttributesAreStored()
|
||||||
|
{
|
||||||
|
$company = Company::factory()->create();
|
||||||
|
$location = Location::factory()->create();
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$rtdLocation = Location::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$supplier = Supplier::factory()->create();
|
||||||
|
$user = User::factory()->createAssets()->create();
|
||||||
|
$userAssigned = User::factory()->create();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($user)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'asset_eol_date' => '2024-06-02',
|
||||||
|
'asset_tag' => 'random_string',
|
||||||
|
'assigned_user' => $userAssigned->id,
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'last_audit_date' => '2023-09-03',
|
||||||
|
'location_id' => $location->id,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'name' => 'A New Asset',
|
||||||
|
'notes' => 'Some notes',
|
||||||
|
'order_number' => '5678',
|
||||||
|
'purchase_cost' => '123.45',
|
||||||
|
'purchase_date' => '2023-09-02',
|
||||||
|
'requestable' => true,
|
||||||
|
'rtd_location_id' => $rtdLocation->id,
|
||||||
|
'serial' => '1234567890',
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'supplier_id' => $supplier->id,
|
||||||
|
'warranty_months' => 10,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
|
||||||
|
$this->assertTrue($asset->adminuser->is($user));
|
||||||
|
|
||||||
|
$this->assertEquals('2024-06-02', $asset->asset_eol_date);
|
||||||
|
$this->assertEquals('random_string', $asset->asset_tag);
|
||||||
|
$this->assertEquals($userAssigned->id, $asset->assigned_to);
|
||||||
|
$this->assertTrue($asset->company->is($company));
|
||||||
|
// I don't see this on the GUI side either, but it's in the docs so I'm guessing that's a mistake? It wasn't in the controller.
|
||||||
|
// $this->assertEquals('2023-09-03', $asset->last_audit_date);
|
||||||
|
$this->assertTrue($asset->location->is($location));
|
||||||
|
$this->assertTrue($asset->model->is($model));
|
||||||
|
$this->assertEquals('A New Asset', $asset->name);
|
||||||
|
$this->assertEquals('Some notes', $asset->notes);
|
||||||
|
$this->assertEquals('5678', $asset->order_number);
|
||||||
|
$this->assertEquals('123.45', $asset->purchase_cost);
|
||||||
|
$this->assertTrue($asset->purchase_date->is('2023-09-02'));
|
||||||
|
$this->assertEquals('1', $asset->requestable);
|
||||||
|
$this->assertTrue($asset->defaultLoc->is($rtdLocation));
|
||||||
|
$this->assertEquals('1234567890', $asset->serial);
|
||||||
|
$this->assertTrue($asset->assetstatus->is($status));
|
||||||
|
$this->assertTrue($asset->supplier->is($supplier));
|
||||||
|
$this->assertEquals(10, $asset->warranty_months);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArchivedDepreciateAndPhysicalCanBeNull()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->ipadModel()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'archive' => null,
|
||||||
|
'depreciate' => null,
|
||||||
|
'physical' => null
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertEquals(0, $asset->archived);
|
||||||
|
$this->assertEquals(1, $asset->physical);
|
||||||
|
$this->assertEquals(0, $asset->depreciate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArchivedDepreciateAndPhysicalCanBeEmpty()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->ipadModel()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'archive' => '',
|
||||||
|
'depreciate' => '',
|
||||||
|
'physical' => ''
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertEquals(0, $asset->archived);
|
||||||
|
$this->assertEquals(1, $asset->physical);
|
||||||
|
$this->assertEquals(0, $asset->depreciate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetEolDateIsCalculatedIfPurchaseDateSet()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->mbp13Model()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'purchase_date' => '2021-01-01',
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertEquals('2024-01-01', $asset->asset_eol_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetEolDateIsNotCalculatedIfPurchaseDateNotSet()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->mbp13Model()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertNull($asset->asset_eol_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetEolExplicitIsSetIfAssetEolDateIsExplicitlySet()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->mbp13Model()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'asset_eol_date' => '2025-01-01',
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertEquals('2025-01-01', $asset->asset_eol_date);
|
||||||
|
$this->assertTrue($asset->eol_explicit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetGetsAssetTagWithAutoIncrement()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
$this->assertNotNull($asset->asset_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetCreationFailsWithNoAssetTagOrAutoIncrement()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->disableAutoIncrement();
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('error');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUniqueSerialNumbersIsEnforcedWhenEnabled()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$serial = '1234567890';
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
$this->settings->enableUniqueSerialNumbers();
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'serial' => $serial,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success');
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'serial' => $serial,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('error');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUniqueSerialNumbersIsNotEnforcedWhenDisabled()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$serial = '1234567890';
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
$this->settings->disableUniqueSerialNumbers();
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'serial' => $serial,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success');
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
'serial' => $serial,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetTagsMustBeUniqueWhenUndeleted()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$asset_tag = '1234567890';
|
||||||
|
|
||||||
|
$this->settings->disableAutoIncrement();
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'asset_tag' => $asset_tag,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success');
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'asset_tag' => $asset_tag,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('error');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAssetTagsCanBeDuplicatedIfDeleted()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$asset_tag = '1234567890';
|
||||||
|
|
||||||
|
$this->settings->disableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'asset_tag' => $asset_tag,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
Asset::find($response['payload']['id'])->delete();
|
||||||
|
|
||||||
|
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'asset_tag' => $asset_tag,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAnAssetCanBeCheckedOutToUserOnStore()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$user = User::factory()->createAssets()->create();
|
||||||
|
$userAssigned = User::factory()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($user)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'assigned_user' => $userAssigned->id,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
|
||||||
|
$this->assertTrue($asset->adminuser->is($user));
|
||||||
|
$this->assertTrue($asset->checkedOutToUser());
|
||||||
|
$this->assertTrue($asset->assignedTo->is($userAssigned));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAnAssetCanBeCheckedOutToLocationOnStore()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$location = Location::factory()->create();
|
||||||
|
$user = User::factory()->createAssets()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($user)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'assigned_location' => $location->id,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$asset = Asset::find($response['payload']['id']);
|
||||||
|
|
||||||
|
$this->assertTrue($asset->adminuser->is($user));
|
||||||
|
$this->assertTrue($asset->checkedOutToLocation());
|
||||||
|
$this->assertTrue($asset->location->is($location));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAnAssetCanBeCheckedOutToAssetOnStore()
|
||||||
|
{
|
||||||
|
$model = AssetModel::factory()->create();
|
||||||
|
$status = Statuslabel::factory()->create();
|
||||||
|
$asset = Asset::factory()->create();
|
||||||
|
$user = User::factory()->createAssets()->create();
|
||||||
|
|
||||||
|
$this->settings->enableAutoIncrement();
|
||||||
|
|
||||||
|
$response = $this->actingAsForApi($user)
|
||||||
|
->postJson(route('api.assets.store'), [
|
||||||
|
'assigned_asset' => $asset->id,
|
||||||
|
'model_id' => $model->id,
|
||||||
|
'status_id' => $status->id,
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertStatusMessageIs('success')
|
||||||
|
->json();
|
||||||
|
|
||||||
|
$apiAsset = Asset::find($response['payload']['id']);
|
||||||
|
|
||||||
|
$this->assertTrue($apiAsset->adminuser->is($user));
|
||||||
|
$this->assertTrue($apiAsset->checkedOutToAsset());
|
||||||
|
// I think this makes sense, but open to a sanity check
|
||||||
|
$this->assertTrue($asset->assignedAssets()->find($response['payload']['id'])->is($apiAsset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,5 +74,18 @@ trait CustomTestMacros
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TestResponse::macro(
|
||||||
|
'assertStatusMessageIs',
|
||||||
|
function (string $message) {
|
||||||
|
Assert::assertEquals(
|
||||||
|
$message,
|
||||||
|
$this['status'],
|
||||||
|
"Response status message was not {$message}"
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,29 @@ class Settings
|
||||||
return $this->update([
|
return $this->update([
|
||||||
'auto_increment_assets' => 1,
|
'auto_increment_assets' => 1,
|
||||||
'auto_increment_prefix' => 'ABCD',
|
'auto_increment_prefix' => 'ABCD',
|
||||||
'next_auto_tag_base' => '123',
|
'next_auto_tag_base' => 123,
|
||||||
'zerofill_count' => 5
|
'zerofill_count' => 5
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableAutoIncrement(): Settings
|
||||||
|
{
|
||||||
|
return $this->update([
|
||||||
|
'auto_increment_assets' => 0,
|
||||||
|
'auto_increment_prefix' => 0,
|
||||||
|
'next_auto_tag_base' => 0,
|
||||||
|
'zerofill_count' => 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function enableUniqueSerialNumbers(): Settings
|
||||||
|
{
|
||||||
|
return $this->update(['unique_serial' => 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disableUniqueSerialNumbers(): Settings
|
||||||
|
{
|
||||||
|
return $this->update(['unique_serial' => 0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enableLdap(): Settings
|
public function enableLdap(): Settings
|
||||||
|
|
|
@ -22,19 +22,16 @@ class AssetModelTest extends TestCase
|
||||||
|
|
||||||
public function testAnAssetModelContainsAssets()
|
public function testAnAssetModelContainsAssets()
|
||||||
{
|
{
|
||||||
$category = Category::factory()->create(
|
$category = Category::factory()->create([
|
||||||
['category_type' => 'asset']
|
'category_type' => 'asset'
|
||||||
);
|
]);
|
||||||
$model = AssetModel::factory()->create([
|
$model = AssetModel::factory()->create([
|
||||||
'category_id' => $category->id,
|
'category_id' => $category->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$asset = Asset::factory()
|
$asset = Asset::factory()->create([
|
||||||
->create(
|
|
||||||
[
|
|
||||||
'model_id' => $model->id
|
'model_id' => $model->id
|
||||||
]
|
]);
|
||||||
);
|
|
||||||
$this->assertEquals(1, $model->assets()->count());
|
$this->assertEquals(1, $model->assets()->count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue