Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions app/Http/Controllers/Api/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1290,9 +1290,19 @@ public function requestable(Request $request): JsonResponse | array

public function assignedAssets(Request $request, Asset $asset) : JsonResponse | array
{
$this->authorize('view', Asset::class);
$this->authorize('view', $asset);

$query = Asset::where([
'assigned_to' => $asset->id,
'assigned_type' => Asset::class,
]);

$total = $query->count();

$assets = $query->applyOffsetAndLimit($total)->get();

return [];
// to do
return (new AssetsTransformer)->transformAssets($assets, $total);
}

public function assignedAccessories(Request $request, Asset $asset) : JsonResponse | array
Expand Down
16 changes: 16 additions & 0 deletions app/Models/SnipeModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
namespace App\Models;

use App\Helpers\Helper;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Request;

class SnipeModel extends Model
{
Expand Down Expand Up @@ -156,6 +158,20 @@ public function setStatusIdAttribute($value)
$this->attributes['status_id'] = $value;
}

/**
* Applies offset (from request) and limit to query.
*
* @param Builder $query
* @param int $total
* @return void
*/
public function scopeApplyOffsetAndLimit(Builder $query, int $total)
{
$offset = (Request::input('offset') > $total) ? $total : app('api_offset_value');
$limit = app('api_limit_value');

$query->skip($offset)->take($limit);
}

protected function displayName(): Attribute
{
Expand Down
84 changes: 84 additions & 0 deletions tests/Feature/Assets/Api/AssignedAssetsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace Tests\Feature\Assets\Api;

use App\Models\Asset;
use App\Models\Company;
use App\Models\User;
use Illuminate\Testing\Fluent\AssertableJson;
use Tests\TestCase;

class AssignedAssetsTest extends TestCase
{
public function test_requires_permission()
{
$this->actingAsForApi(User::factory()->create())
->getJson(route('api.assets.assigned_assets', Asset::factory()->create()))
->assertForbidden();
}

public function test_adheres_to_company_scoping()
{
$this->settings->enableMultipleFullCompanySupport();

[$companyA, $companyB] = Company::factory()->count(2)->create();

$asset = Asset::factory()->for($companyA)->create();

$user = User::factory()->for($companyB)->viewAssets()->create();

$this->actingAsForApi($user)
->getJson(route('api.assets.assigned_assets', $asset))
->assertOk()
->assertStatusMessageIs('error')
->assertMessagesAre('Asset not found');
}

public function test_can_get_assets_assigned_to_specific_asset()
{
$unassociatedAsset = Asset::factory()->create();

$asset = Asset::factory()->hasAssignedAssets(2)->create();

$assetsAssignedToAsset = Asset::where([
'assigned_to' => $asset->id,
'assigned_type' => Asset::class,
])->get();

$this->actingAsForApi(User::factory()->viewAssets()->create())
->getJson(route('api.assets.assigned_assets', $asset))
->assertOk()
->assertResponseContainsInRows($assetsAssignedToAsset, 'serial')
->assertResponseDoesNotContainInRows($unassociatedAsset, 'serial')
->assertJson(function (AssertableJson $json) {
$json->where('total', 2)
->count('rows', 2)
->etc();
});
}

public function test_adheres_to_offset_and_limit()
{
$asset = Asset::factory()->hasAssignedAssets(2)->create();

$assetsAssignedToAsset = Asset::where([
'assigned_to' => $asset->id,
'assigned_type' => Asset::class,
])->get();

$this->actingAsForApi(User::factory()->viewAssets()->create())
->getJson(route('api.assets.assigned_assets', [
'asset' => $asset,
'offset' => 1,
'limit' => 1,
]))
->assertOk()
->assertResponseDoesNotContainInRows($assetsAssignedToAsset->first(), 'serial')
->assertResponseContainsInRows($assetsAssignedToAsset->last(), 'serial')
->assertJson(function (AssertableJson $json) {
$json->where('total', 2)
->count('rows', 1)
->etc();
});
}
}
18 changes: 12 additions & 6 deletions tests/Support/CustomTestMacros.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ protected function registerCustomMacros()

TestResponse::macro(
'assertResponseContainsInRows',
function (Model $model, string $property = 'name') use ($guardAgainstNullProperty) {
$guardAgainstNullProperty($model, $property);
function (iterable|Model $models, string $property = 'name') use ($guardAgainstNullProperty) {
if ($models instanceof Model) {
$models = [$models];
}

Assert::assertTrue(
collect($this['rows'])->pluck($property)->contains(e($model->{$property})),
"Response did not contain the expected value: {$model->{$property}}"
);
foreach ($models as $model) {
$guardAgainstNullProperty($model, $property);

Assert::assertTrue(
collect($this['rows'])->pluck($property)->contains(e($model->{$property})),
"Response did not contain the expected value: {$model->{$property}}"
);
}

return $this;
}
Expand Down
Loading