From 3f07f682defd228dc51d01b962353978e6e5eed8 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 16 Sep 2024 16:35:21 -0700 Subject: [PATCH 01/86] Migrate existing tests to TestsPermissionsRequirement --- tests/Feature/Accessories/Api/IndexAccessoryTest.php | 5 +++-- tests/Feature/Accessories/Api/ShowAccessoryTest.php | 5 +++-- tests/Feature/Accessories/Api/StoreAccessoryTest.php | 5 +++-- tests/Feature/Accessories/Api/UpdateAccessoryTest.php | 5 +++-- tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/Feature/Accessories/Api/IndexAccessoryTest.php b/tests/Feature/Accessories/Api/IndexAccessoryTest.php index 509e6fd452..aeadb808bd 100644 --- a/tests/Feature/Accessories/Api/IndexAccessoryTest.php +++ b/tests/Feature/Accessories/Api/IndexAccessoryTest.php @@ -3,11 +3,12 @@ namespace Tests\Feature\Accessories\Api; use App\Models\User; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class IndexAccessoryTest extends TestCase +class IndexAccessoryTest extends TestCase implements TestsPermissionsRequirement { - public function testPermissionRequiredToViewAccessoriesIndex() + public function testRequiresPermission() { $this->actingAsForApi(User::factory()->create()) ->getJson(route('api.accessories.index')) diff --git a/tests/Feature/Accessories/Api/ShowAccessoryTest.php b/tests/Feature/Accessories/Api/ShowAccessoryTest.php index 2bc3e88bfc..da35eca3e0 100644 --- a/tests/Feature/Accessories/Api/ShowAccessoryTest.php +++ b/tests/Feature/Accessories/Api/ShowAccessoryTest.php @@ -4,11 +4,12 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Accessory; use App\Models\User; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class ShowAccessoryTest extends TestCase +class ShowAccessoryTest extends TestCase implements TestsPermissionsRequirement { - public function testPermissionRequiredToShowAccessory() + public function testRequiresPermission() { $accessory = Accessory::factory()->create(); diff --git a/tests/Feature/Accessories/Api/StoreAccessoryTest.php b/tests/Feature/Accessories/Api/StoreAccessoryTest.php index d29ff32f6e..1c2d3d5fd8 100644 --- a/tests/Feature/Accessories/Api/StoreAccessoryTest.php +++ b/tests/Feature/Accessories/Api/StoreAccessoryTest.php @@ -3,11 +3,12 @@ namespace Tests\Feature\Accessories\Api; use App\Models\User; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class StoreAccessoryTest extends TestCase +class StoreAccessoryTest extends TestCase implements TestsPermissionsRequirement { - public function testPermissionRequiredToStoreAccessory() + public function testRequiresPermission() { $this->actingAsForApi(User::factory()->create()) ->postJson(route('api.accessories.store')) diff --git a/tests/Feature/Accessories/Api/UpdateAccessoryTest.php b/tests/Feature/Accessories/Api/UpdateAccessoryTest.php index 45923651f2..932623fb36 100644 --- a/tests/Feature/Accessories/Api/UpdateAccessoryTest.php +++ b/tests/Feature/Accessories/Api/UpdateAccessoryTest.php @@ -4,11 +4,12 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Accessory; use App\Models\User; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class UpdateAccessoryTest extends TestCase +class UpdateAccessoryTest extends TestCase implements TestsPermissionsRequirement { - public function testPermissionRequiredToUpdateAccessory() + public function testRequiresPermission() { $accessory = Accessory::factory()->create(); diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 2b37797fb6..819d4430e1 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -7,11 +7,12 @@ use App\Models\Actionlog; use App\Models\User; use App\Notifications\CheckoutAccessoryNotification; use Illuminate\Support\Facades\Notification; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class AccessoryCheckoutTest extends TestCase +class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirement { - public function testCheckingOutAccessoryRequiresCorrectPermission() + public function testRequiresPermission() { $this->actingAsForApi(User::factory()->create()) ->postJson(route('api.accessories.checkout', Accessory::factory()->create())) From eb35608bb59a3fc72c7fc55c5431462aef04b040 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 16 Sep 2024 16:35:33 -0700 Subject: [PATCH 02/86] Remove call handled by form request --- app/Http/Controllers/Api/AccessoriesController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Http/Controllers/Api/AccessoriesController.php b/app/Http/Controllers/Api/AccessoriesController.php index b1506e4f40..578c474889 100644 --- a/app/Http/Controllers/Api/AccessoriesController.php +++ b/app/Http/Controllers/Api/AccessoriesController.php @@ -133,7 +133,6 @@ class AccessoriesController extends Controller */ public function store(StoreAccessoryRequest $request) { - $this->authorize('create', Accessory::class); $accessory = new Accessory; $accessory->fill($request->all()); $accessory = $request->handleImages($accessory); From e835637ef0120a96012951a965848ecb8465e69f Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 16 Sep 2024 16:40:10 -0700 Subject: [PATCH 03/86] Add accessory checkin test --- .../Checkins/Api/AccessoryCheckinTest.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/Feature/Checkins/Api/AccessoryCheckinTest.php diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php new file mode 100644 index 0000000000..925d9dd050 --- /dev/null +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -0,0 +1,20 @@ +checkedOutToUser()->create(); + + $this->actingAsForApi(User::factory()->create()) + ->postJson(route('api.accessories.checkin', $accessory)) + ->assertForbidden(); + } +} From 8eb1c487bcaa1fb6ec71d85985226d49c01e3cea Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 16 Sep 2024 16:52:10 -0700 Subject: [PATCH 04/86] implement FMCS test for accessory index --- .../Accessories/Api/IndexAccessoryTest.php | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Accessories/Api/IndexAccessoryTest.php b/tests/Feature/Accessories/Api/IndexAccessoryTest.php index aeadb808bd..4722bdd551 100644 --- a/tests/Feature/Accessories/Api/IndexAccessoryTest.php +++ b/tests/Feature/Accessories/Api/IndexAccessoryTest.php @@ -2,11 +2,14 @@ namespace Tests\Feature\Accessories\Api; +use App\Models\Accessory; +use App\Models\Company; use App\Models\User; +use Tests\Concerns\TestsMultipleFullCompanySupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class IndexAccessoryTest extends TestCase implements TestsPermissionsRequirement +class IndexAccessoryTest extends TestCase implements TestsMultipleFullCompanySupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -14,4 +17,40 @@ class IndexAccessoryTest extends TestCase implements TestsPermissionsRequirement ->getJson(route('api.accessories.index')) ->assertForbidden(); } + + public function testAdheresToMultipleFullCompanySupportScoping() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + + $accessoryA = Accessory::factory()->for($companyA)->create(['name' => 'Accessory A']); + $accessoryB = Accessory::factory()->for($companyB)->create(['name' => 'Accessory B']); + $accessoryC = Accessory::factory()->for($companyB)->create(['name' => 'Accessory C']); + + $superUser = $companyA->users()->save(User::factory()->superuser()->make()); + $userInCompanyA = $companyA->users()->save(User::factory()->viewAccessories()->make()); + $userInCompanyB = $companyB->users()->save(User::factory()->viewAccessories()->make()); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userInCompanyA) + ->getJson(route('api.accessories.index')) + ->assertOk() + ->assertResponseContainsInRows($accessoryA) + ->assertResponseDoesNotContainInRows($accessoryB) + ->assertResponseDoesNotContainInRows($accessoryC); + + $this->actingAsForApi($userInCompanyB) + ->getJson(route('api.accessories.index')) + ->assertOk() + ->assertResponseDoesNotContainInRows($accessoryA) + ->assertResponseContainsInRows($accessoryB) + ->assertResponseContainsInRows($accessoryC); + + $this->actingAsForApi($superUser) + ->getJson(route('api.accessories.index')) + ->assertOk() + ->assertResponseContainsInRows($accessoryA) + ->assertResponseContainsInRows($accessoryB) + ->assertResponseContainsInRows($accessoryC); + } } From 12fd9cd97a30ca1ab715fd923c40d3558706e88e Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 16 Sep 2024 17:00:08 -0700 Subject: [PATCH 05/86] Update interface name --- tests/Feature/Accessories/Api/IndexAccessoryTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Accessories/Api/IndexAccessoryTest.php b/tests/Feature/Accessories/Api/IndexAccessoryTest.php index 4722bdd551..999c0f97ff 100644 --- a/tests/Feature/Accessories/Api/IndexAccessoryTest.php +++ b/tests/Feature/Accessories/Api/IndexAccessoryTest.php @@ -5,11 +5,11 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Accessory; use App\Models\Company; use App\Models\User; -use Tests\Concerns\TestsMultipleFullCompanySupport; +use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class IndexAccessoryTest extends TestCase implements TestsMultipleFullCompanySupport, TestsPermissionsRequirement +class IndexAccessoryTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -18,7 +18,7 @@ class IndexAccessoryTest extends TestCase implements TestsMultipleFullCompanySup ->assertForbidden(); } - public function testAdheresToMultipleFullCompanySupportScoping() + public function testAdheresToFullMultipleCompaniesSupportScoping() { [$companyA, $companyB] = Company::factory()->count(2)->create(); From 7b31df7c148566274527317bb5bf006e5764fda8 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Tue, 17 Sep 2024 09:11:58 -0700 Subject: [PATCH 06/86] Begin additional test case --- .../Checkins/Api/AccessoryCheckinTest.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index 925d9dd050..8321fe9953 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -3,11 +3,13 @@ namespace Tests\Feature\Checkins\Api; use App\Models\Accessory; +use App\Models\Company; use App\Models\User; +use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class AccessoryCheckinTest extends TestCase implements TestsPermissionsRequirement +class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -17,4 +19,24 @@ class AccessoryCheckinTest extends TestCase implements TestsPermissionsRequireme ->postJson(route('api.accessories.checkin', $accessory)) ->assertForbidden(); } + + public function testAdheresToFullMultipleCompaniesSupportScoping() + { + $this->markTestIncomplete(); + + $this->withoutExceptionHandling(); + + [$companyA, $companyB] = Company::factory()->count(2)->create(); + + $userInCompanyA = User::factory()->for($companyA)->checkinAccessories()->create(); + $accessoryForCompanyB = Accessory::factory()->for($companyB)->checkedOutToUser()->create(); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userInCompanyA) + ->postJson(route('api.accessories.checkin', $accessoryForCompanyB)) + ->assertStatusMessageIs('error'); + + // @todo: + } } From fa1968624885e51b71f4a77215cec01beaae01e5 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:18:21 -0700 Subject: [PATCH 07/86] Implement test --- .../Checkins/Api/AccessoryCheckinTest.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index 8321fe9953..fd0fc075f4 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -22,21 +22,27 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie public function testAdheresToFullMultipleCompaniesSupportScoping() { - $this->markTestIncomplete(); - - $this->withoutExceptionHandling(); - [$companyA, $companyB] = Company::factory()->count(2)->create(); + $superUser = $companyA->users()->save(User::factory()->superuser()->make()); $userInCompanyA = User::factory()->for($companyA)->checkinAccessories()->create(); $accessoryForCompanyB = Accessory::factory()->for($companyB)->checkedOutToUser()->create(); + $anotherAccessoryForCompanyB = Accessory::factory()->for($companyB)->checkedOutToUser()->create(); + + $this->assertEquals(1, $accessoryForCompanyB->checkouts->count()); + $this->assertEquals(1, $anotherAccessoryForCompanyB->checkouts->count()); $this->settings->enableMultipleFullCompanySupport(); $this->actingAsForApi($userInCompanyA) ->postJson(route('api.accessories.checkin', $accessoryForCompanyB)) - ->assertStatusMessageIs('error'); + ->assertForbidden(); - // @todo: + $this->actingAsForApi($superUser) + ->postJson(route('api.accessories.checkin', $anotherAccessoryForCompanyB)) + ->assertStatusMessageIs('success'); + + $this->assertEquals(1, $accessoryForCompanyB->fresh()->checkouts->count(), 'Accessory should not be checked in'); + $this->assertEquals(0, $anotherAccessoryForCompanyB->fresh()->checkouts->count(), 'Accessory should be checked in'); } } From 832e50a71ebcda26451f090042cb072bae05c4f3 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:19:41 -0700 Subject: [PATCH 08/86] Implement test --- tests/Feature/Checkins/Api/AccessoryCheckinTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index fd0fc075f4..58c5514190 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -45,4 +45,17 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie $this->assertEquals(1, $accessoryForCompanyB->fresh()->checkouts->count(), 'Accessory should not be checked in'); $this->assertEquals(0, $anotherAccessoryForCompanyB->fresh()->checkouts->count(), 'Accessory should be checked in'); } + + public function testCanCheckinAccessory() + { + $accessory = Accessory::factory()->checkedOutToUser()->create(); + + $this->assertEquals(1, $accessory->checkouts->count()); + + $this->actingAsForApi(User::factory()->checkinAccessories()->create()) + ->postJson(route('api.accessories.checkin', $accessory)) + ->assertStatusMessageIs('success'); + + $this->assertEquals(0, $accessory->fresh()->checkouts->count(), 'Accessory should be checked in'); + } } From d5f659024c06a8dc3a6573f1b2d7eddf25b698c4 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:27:09 -0700 Subject: [PATCH 09/86] Add test for logging --- .../Checkins/Api/AccessoryCheckinTest.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index 58c5514190..d44a05b310 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -58,4 +58,25 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie $this->assertEquals(0, $accessory->fresh()->checkouts->count(), 'Accessory should be checked in'); } + + public function testCheckinIsLogged() + { + $user = User::factory()->create(); + $actor = User::factory()->checkinAccessories()->create(); + + $accessory = Accessory::factory()->checkedOutToUser($user)->create(); + + $this->actingAsForApi($actor) + ->postJson(route('api.accessories.checkin', $accessory)) + ->assertStatusMessageIs('success'); + + $this->assertDatabaseHas('action_logs', [ + 'user_id' => $actor->id, + 'action_type' => 'checkin from', + 'target_id' => $user->id, + 'target_type' => User::class, + 'item_id' => $accessory->id, + 'item_type' => Accessory::class, + ]); + } } From 636c776620a012937c7f79cd67dde9cf7c6a92cf Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:27:37 -0700 Subject: [PATCH 10/86] Remove dead code --- app/Http/Controllers/Api/AccessoriesController.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/Http/Controllers/Api/AccessoriesController.php b/app/Http/Controllers/Api/AccessoriesController.php index 578c474889..acfdcef870 100644 --- a/app/Http/Controllers/Api/AccessoriesController.php +++ b/app/Http/Controllers/Api/AccessoriesController.php @@ -320,7 +320,7 @@ class AccessoriesController extends Controller $accessory = Accessory::find($accessory_checkout->accessory_id); $this->authorize('checkin', $accessory); - $logaction = $accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note')); + $accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note')); // Was the accessory updated? if ($accessory_checkout->delete()) { @@ -328,14 +328,6 @@ class AccessoriesController extends Controller $user = User::find($accessory_checkout->assigned_to); } - $data['log_id'] = $logaction->id; - $data['first_name'] = $user->first_name; - $data['last_name'] = $user->last_name; - $data['item_name'] = $accessory->name; - $data['checkin_date'] = $logaction->created_at; - $data['item_tag'] = ''; - $data['note'] = $logaction->note; - return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.checkin.success'))); } From 9b293afaac70370ad7741c306e7b14c47eecf3ce Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:28:29 -0700 Subject: [PATCH 11/86] Remove more dead code --- app/Models/Loggable.php | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index ae5d554882..a246503165 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -117,7 +117,6 @@ trait Loggable */ public function logCheckin($target, $note, $action_date = null, $originalValues = []) { - $settings = Setting::getSettings(); $log = new Actionlog; if($target != null){ @@ -171,39 +170,6 @@ trait Loggable $log->logaction('checkin from'); -// $params = [ -// 'target' => $target, -// 'item' => $log->item, -// 'admin' => $log->user, -// 'note' => $note, -// 'target_type' => $log->target_type, -// 'settings' => $settings, -// ]; -// -// -// $checkinClass = null; -// -// if (method_exists($target, 'notify')) { -// try { -// $target->notify(new static::$checkinClass($params)); -// } catch (\Exception $e) { -// Log::debug($e); -// } -// -// } -// -// // Send to the admin, if settings dictate -// $recipient = new \App\Models\Recipients\AdminRecipient(); -// -// if (($settings->admin_cc_email!='') && (static::$checkinClass!='')) { -// try { -// $recipient->notify(new static::$checkinClass($params)); -// } catch (\Exception $e) { -// Log::debug($e); -// } -// -// } - return $log; } From a6bcd3c0c2b03c81b45ece70d453e767d277acc0 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:47:59 -0700 Subject: [PATCH 12/86] Add validation test --- .../Accessories/Api/StoreAccessoryTest.php | 19 +++++++++++++++++ tests/Support/CustomTestMacros.php | 21 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/Feature/Accessories/Api/StoreAccessoryTest.php b/tests/Feature/Accessories/Api/StoreAccessoryTest.php index 1c2d3d5fd8..496b8e9b3a 100644 --- a/tests/Feature/Accessories/Api/StoreAccessoryTest.php +++ b/tests/Feature/Accessories/Api/StoreAccessoryTest.php @@ -14,4 +14,23 @@ class StoreAccessoryTest extends TestCase implements TestsPermissionsRequirement ->postJson(route('api.accessories.store')) ->assertForbidden(); } + + public function testValidation() + { + $this->actingAsForApi(User::factory()->createAccessories()->create()) + ->postJson(route('api.accessories.store'), [ + // + ]) + ->assertStatusMessageIs('error') + ->assertMessagesContains([ + 'category_id', + 'name', + 'qty', + ]); + } + + public function testCanStoreAccessory() + { + $this->markTestIncomplete(); + } } diff --git a/tests/Support/CustomTestMacros.php b/tests/Support/CustomTestMacros.php index 993f449021..9c0caaf959 100644 --- a/tests/Support/CustomTestMacros.php +++ b/tests/Support/CustomTestMacros.php @@ -100,5 +100,26 @@ trait CustomTestMacros return $this; } ); + + TestResponse::macro( + 'assertMessagesContains', + function (array|string $keys) { + Assert::assertArrayHasKey('messages', $this, 'Response did not contain any messages'); + + if (is_string($keys)) { + $keys = [$keys]; + } + + foreach ($keys as $key) { + Assert::assertArrayHasKey( + $key, + $this['messages'], + "Response messages did not contain the key: {$key}" + ); + } + + return $this; + } + ); } } From 607f29030f13f82b40ccacefeec5f329f250b887 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:53:27 -0700 Subject: [PATCH 13/86] Stub out test --- .../Accessories/Api/StoreAccessoryTest.php | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Accessories/Api/StoreAccessoryTest.php b/tests/Feature/Accessories/Api/StoreAccessoryTest.php index 496b8e9b3a..4b5d754633 100644 --- a/tests/Feature/Accessories/Api/StoreAccessoryTest.php +++ b/tests/Feature/Accessories/Api/StoreAccessoryTest.php @@ -2,11 +2,14 @@ namespace Tests\Feature\Accessories\Api; +use App\Models\Category; +use App\Models\Company; use App\Models\User; +use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class StoreAccessoryTest extends TestCase implements TestsPermissionsRequirement +class StoreAccessoryTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -15,6 +18,29 @@ class StoreAccessoryTest extends TestCase implements TestsPermissionsRequirement ->assertForbidden(); } + public function testAdheresToFullMultipleCompaniesSupportScoping() + { + $this->markTestSkipped('This behavior is not implemented'); + + [$companyA, $companyB] = Company::factory()->count(2)->create(); + $userInCompanyA = User::factory()->for($companyA)->createAccessories()->create(); + + $this->settings->enableMultipleFullCompanySupport(); + + // attempt to store an accessory for company B + $this->actingAsForApi($userInCompanyA) + ->postJson(route('api.accessories.store'), [ + 'category_id' => Category::factory()->forAccessories()->create()->id, + 'name' => 'Accessory A', + 'qty' => 1, + 'company_id' => $companyB->id, + ])->assertStatusMessageIs('error'); + + $this->assertDatabaseMissing('accessories', [ + 'name' => 'Accessory A', + ]); + } + public function testValidation() { $this->actingAsForApi(User::factory()->createAccessories()->create()) From 8b50ef077dc52c09bddd4743336aeea2d2d9de98 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 11:58:33 -0700 Subject: [PATCH 14/86] Implement test --- .../Accessories/Api/StoreAccessoryTest.php | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Accessories/Api/StoreAccessoryTest.php b/tests/Feature/Accessories/Api/StoreAccessoryTest.php index 4b5d754633..22ba715519 100644 --- a/tests/Feature/Accessories/Api/StoreAccessoryTest.php +++ b/tests/Feature/Accessories/Api/StoreAccessoryTest.php @@ -4,6 +4,9 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Category; use App\Models\Company; +use App\Models\Location; +use App\Models\Manufacturer; +use App\Models\Supplier; use App\Models\User; use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; @@ -31,13 +34,13 @@ class StoreAccessoryTest extends TestCase implements TestsFullMultipleCompaniesS $this->actingAsForApi($userInCompanyA) ->postJson(route('api.accessories.store'), [ 'category_id' => Category::factory()->forAccessories()->create()->id, - 'name' => 'Accessory A', + 'name' => 'My Awesome Accessory', 'qty' => 1, 'company_id' => $companyB->id, ])->assertStatusMessageIs('error'); $this->assertDatabaseMissing('accessories', [ - 'name' => 'Accessory A', + 'name' => 'My Awesome Accessory', ]); } @@ -57,6 +60,39 @@ class StoreAccessoryTest extends TestCase implements TestsFullMultipleCompaniesS public function testCanStoreAccessory() { - $this->markTestIncomplete(); + $category = Category::factory()->forAccessories()->create(); + $company = Company::factory()->create(); + $location = Location::factory()->create(); + $manufacturer = Manufacturer::factory()->create(); + $supplier = Supplier::factory()->create(); + + $this->actingAsForApi(User::factory()->createAccessories()->create()) + ->postJson(route('api.accessories.store'), [ + 'name' => 'My Awesome Accessory', + 'qty' => 2, + 'order_number' => '12345', + 'purchase_cost' => 100.00, + 'purchase_date' => '2024-09-18', + 'model_number' => '98765', + 'category_id' => $category->id, + 'company_id' => $company->id, + 'location_id' => $location->id, + 'manufacturer_id' => $manufacturer->id, + 'supplier_id' => $supplier->id, + ])->assertStatusMessageIs('success'); + + $this->assertDatabaseHas('accessories', [ + 'name' => 'My Awesome Accessory', + 'qty' => 2, + 'order_number' => '12345', + 'purchase_cost' => 100.00, + 'purchase_date' => '2024-09-18', + 'model_number' => '98765', + 'category_id' => $category->id, + 'company_id' => $company->id, + 'location_id' => $location->id, + 'manufacturer_id' => $manufacturer->id, + 'supplier_id' => $supplier->id, + ]); } } From a071fff954b8f90b7a5e5a4df3f8a5a7d45598c1 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 12:32:14 -0700 Subject: [PATCH 15/86] Implement tests --- .../Accessories/Api/ShowAccessoryTest.php | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Accessories/Api/ShowAccessoryTest.php b/tests/Feature/Accessories/Api/ShowAccessoryTest.php index da35eca3e0..117d725007 100644 --- a/tests/Feature/Accessories/Api/ShowAccessoryTest.php +++ b/tests/Feature/Accessories/Api/ShowAccessoryTest.php @@ -3,11 +3,13 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Accessory; +use App\Models\Company; use App\Models\User; +use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class ShowAccessoryTest extends TestCase implements TestsPermissionsRequirement +class ShowAccessoryTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -17,4 +19,43 @@ class ShowAccessoryTest extends TestCase implements TestsPermissionsRequirement ->getJson(route('api.accessories.show', $accessory)) ->assertForbidden(); } + + public function testAdheresToFullMultipleCompaniesSupportScoping() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + + $accessoryForCompanyA = Accessory::factory()->for($companyA)->create(); + + $superuser = User::factory()->superuser()->create(); + $userForCompanyB = User::factory()->for($companyB)->viewAccessories()->create(); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userForCompanyB) + ->getJson(route('api.accessories.show', $accessoryForCompanyA)) + ->assertOk() + ->assertStatusMessageIs('error'); + + $this->actingAsForApi($superuser) + ->getJson(route('api.accessories.show', $accessoryForCompanyA)) + ->assertOk() + ->assertJsonFragment([ + 'id' => $accessoryForCompanyA->id, + ]); + } + + public function testCanGetSingleAccessory() + { + $accessory = Accessory::factory()->checkedOutToUser()->create(['name' => 'My Accessory']); + + $this->actingAsForApi(User::factory()->viewAccessories()->create()) + ->getJson(route('api.accessories.show', $accessory)) + ->assertOk() + ->assertJsonFragment([ + 'id' => $accessory->id, + 'name' => 'My Accessory', + 'checkouts_count' => 1, + ]); + + } } From 86f13a9735358ce0ce51205a439ce8fc7df5197c Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 18 Sep 2024 16:13:34 -0700 Subject: [PATCH 16/86] Add index test --- .../Feature/Accessories/Api/IndexAccessoryTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Feature/Accessories/Api/IndexAccessoryTest.php b/tests/Feature/Accessories/Api/IndexAccessoryTest.php index 999c0f97ff..96263f5380 100644 --- a/tests/Feature/Accessories/Api/IndexAccessoryTest.php +++ b/tests/Feature/Accessories/Api/IndexAccessoryTest.php @@ -53,4 +53,18 @@ class IndexAccessoryTest extends TestCase implements TestsFullMultipleCompaniesS ->assertResponseContainsInRows($accessoryB) ->assertResponseContainsInRows($accessoryC); } + + public function testCanGetAccessories() + { + $user = User::factory()->viewAccessories()->create(); + + $accessoryA = Accessory::factory()->create(['name' => 'Accessory A']); + $accessoryB = Accessory::factory()->create(['name' => 'Accessory B']); + + $this->actingAsForApi($user) + ->getJson(route('api.accessories.index')) + ->assertOk() + ->assertResponseContainsInRows($accessoryA) + ->assertResponseContainsInRows($accessoryB); + } } From 9b22d6d493734e2ff55b6b2e80f682b98f92e6e4 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 19 Sep 2024 11:24:01 -0700 Subject: [PATCH 17/86] Add tests for accessory checkouts endpoint --- database/factories/AccessoryFactory.php | 15 +++++ .../Api/IndexAccessoryCheckoutsTest.php | 64 +++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php diff --git a/database/factories/AccessoryFactory.php b/database/factories/AccessoryFactory.php index 356b367ec4..38d159f423 100644 --- a/database/factories/AccessoryFactory.php +++ b/database/factories/AccessoryFactory.php @@ -156,4 +156,19 @@ class AccessoryFactory extends Factory ]); }); } + + public function checkedOutToUsers(array $users) + { + return $this->afterCreating(function (Accessory $accessory) use ($users) { + foreach ($users as $user) { + $accessory->checkouts()->create([ + 'accessory_id' => $accessory->id, + 'created_at' => Carbon::now(), + 'user_id' => 1, + 'assigned_to' => $user->id, + 'assigned_type' => User::class, + ]); + } + }); + } } diff --git a/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php b/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php new file mode 100644 index 0000000000..cad1a03ffd --- /dev/null +++ b/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php @@ -0,0 +1,64 @@ +create(); + + $this->actingAsForApi(User::factory()->create()) + ->getJson(route('api.accessories.checkedout', $accessory)) + ->assertForbidden(); + } + + public function testAdheresToFullMultipleCompaniesSupportScoping() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + + $accessoryA = Accessory::factory()->for($companyA)->create(); + $accessoryB = Accessory::factory()->for($companyB)->create(); + + $superuser = User::factory()->superuser()->create(); + $userInCompanyA = $companyA->users()->save(User::factory()->viewAccessories()->make()); + $userInCompanyB = $companyB->users()->save(User::factory()->viewAccessories()->make()); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userInCompanyA) + ->getJson(route('api.accessories.checkedout', $accessoryB)) + ->assertStatusMessageIs('error'); + + $this->actingAsForApi($userInCompanyB) + ->getJson(route('api.accessories.checkedout', $accessoryA)) + ->assertStatusMessageIs('error'); + + $this->actingAsForApi($superuser) + ->getJson(route('api.accessories.checkedout', $accessoryA)) + ->assertOk(); + } + + public function testCanGetAccessoryCheckouts() + { + [$userA, $userB] = User::factory()->count(2)->create(); + + $accessory = Accessory::factory()->checkedOutToUsers([$userA, $userB])->create(); + + $this->assertEquals(2, $accessory->checkouts()->count()); + + $this->actingAsForApi(User::factory()->viewAccessories()->create()) + ->getJson(route('api.accessories.checkedout', $accessory)) + ->assertOk() + ->assertJsonPath('total', 2) + ->assertJsonPath('rows.0.assigned_to.id', $userA->id) + ->assertJsonPath('rows.1.assigned_to.id', $userB->id); + } +} From 21378904969e0ad166355cd8a92b2bcc74978510 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 19 Sep 2024 11:33:20 -0700 Subject: [PATCH 18/86] Remove dead code --- app/Http/Controllers/Api/AccessoriesController.php | 3 --- database/factories/AccessoryFactory.php | 1 - 2 files changed, 4 deletions(-) diff --git a/app/Http/Controllers/Api/AccessoriesController.php b/app/Http/Controllers/Api/AccessoriesController.php index acfdcef870..d88b5c6849 100644 --- a/app/Http/Controllers/Api/AccessoriesController.php +++ b/app/Http/Controllers/Api/AccessoriesController.php @@ -192,9 +192,6 @@ class AccessoriesController extends Controller $this->authorize('view', Accessory::class); $accessory = Accessory::with('lastCheckout')->findOrFail($id); - if (! Company::isCurrentUserHasAccess($accessory)) { - return ['total' => 0, 'rows' => []]; - } $offset = request('offset', 0); $limit = request('limit', 50); diff --git a/database/factories/AccessoryFactory.php b/database/factories/AccessoryFactory.php index 38d159f423..178f8fa9ad 100644 --- a/database/factories/AccessoryFactory.php +++ b/database/factories/AccessoryFactory.php @@ -3,7 +3,6 @@ namespace Database\Factories; use App\Models\Accessory; -use App\Models\AccessoryCheckout; use App\Models\Category; use App\Models\Location; use App\Models\Manufacturer; From a5be18bb14242da7d503fe8b6e1c5d31ad1a07e8 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 19 Sep 2024 11:55:15 -0700 Subject: [PATCH 19/86] Add test for limit and offset --- .../Api/IndexAccessoryCheckoutsTest.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php b/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php index cad1a03ffd..38f1e99e5d 100644 --- a/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php +++ b/tests/Feature/Accessories/Api/IndexAccessoryCheckoutsTest.php @@ -61,4 +61,24 @@ class IndexAccessoryCheckoutsTest extends TestCase implements TestsFullMultipleC ->assertJsonPath('rows.0.assigned_to.id', $userA->id) ->assertJsonPath('rows.1.assigned_to.id', $userB->id); } + + public function testCanGetAccessoryCheckoutsWithOffsetAndLimitInQueryString() + { + [$userA, $userB, $userC] = User::factory()->count(3)->create(); + + $accessory = Accessory::factory()->checkedOutToUsers([$userA, $userB, $userC])->create(); + + $actor = $this->actingAsForApi(User::factory()->viewAccessories()->create()); + + $actor->getJson(route('api.accessories.checkedout', ['accessory' => $accessory->id, 'limit' => 1])) + ->assertOk() + ->assertJsonPath('total', 3) + ->assertJsonPath('rows.0.assigned_to.id', $userA->id); + + $actor->getJson(route('api.accessories.checkedout', ['accessory' => $accessory->id, 'limit' => 2, 'offset' => 1])) + ->assertOk() + ->assertJsonPath('total', 3) + ->assertJsonPath('rows.0.assigned_to.id', $userB->id) + ->assertJsonPath('rows.1.assigned_to.id', $userC->id); + } } From fff069824b91753a5b0bbd042f7fe0e9d9240aac Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 19 Sep 2024 12:11:03 -0700 Subject: [PATCH 20/86] Add tests for update accessory endpoint --- .../Accessories/Api/UpdateAccessoryTest.php | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Accessories/Api/UpdateAccessoryTest.php b/tests/Feature/Accessories/Api/UpdateAccessoryTest.php index 932623fb36..a0009a732a 100644 --- a/tests/Feature/Accessories/Api/UpdateAccessoryTest.php +++ b/tests/Feature/Accessories/Api/UpdateAccessoryTest.php @@ -3,11 +3,17 @@ namespace Tests\Feature\Accessories\Api; use App\Models\Accessory; +use App\Models\Category; +use App\Models\Company; +use App\Models\Location; +use App\Models\Manufacturer; +use App\Models\Supplier; use App\Models\User; +use Tests\Concerns\TestsFullMultipleCompaniesSupport; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; -class UpdateAccessoryTest extends TestCase implements TestsPermissionsRequirement +class UpdateAccessoryTest extends TestCase implements TestsFullMultipleCompaniesSupport, TestsPermissionsRequirement { public function testRequiresPermission() { @@ -17,4 +23,84 @@ class UpdateAccessoryTest extends TestCase implements TestsPermissionsRequiremen ->patchJson(route('api.accessories.update', $accessory)) ->assertForbidden(); } + + public function testAdheresToFullMultipleCompaniesSupportScoping() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + + $accessoryA = Accessory::factory()->for($companyA)->create(['name' => 'A Name to Change']); + $accessoryB = Accessory::factory()->for($companyB)->create(['name' => 'A Name to Change']); + $accessoryC = Accessory::factory()->for($companyB)->create(['name' => 'A Name to Change']); + + $superuser = User::factory()->superuser()->create(); + $userInCompanyA = $companyA->users()->save(User::factory()->editAccessories()->make()); + $userInCompanyB = $companyB->users()->save(User::factory()->editAccessories()->make()); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userInCompanyA) + ->patchJson(route('api.accessories.update', $accessoryB), ['name' => 'New Name']) + ->assertStatusMessageIs('error'); + + $this->actingAsForApi($userInCompanyB) + ->patchJson(route('api.accessories.update', $accessoryA), ['name' => 'New Name']) + ->assertStatusMessageIs('error'); + + $this->actingAsForApi($superuser) + ->patchJson(route('api.accessories.update', $accessoryC), ['name' => 'New Name']) + ->assertOk(); + + $this->assertEquals('A Name to Change', $accessoryA->fresh()->name); + $this->assertEquals('A Name to Change', $accessoryB->fresh()->name); + $this->assertEquals('New Name', $accessoryC->fresh()->name); + } + + public function testCanUpdateAccessoryViaPatch() + { + [$categoryA, $categoryB] = Category::factory()->count(2)->create(); + [$companyA, $companyB] = Company::factory()->count(2)->create(); + [$locationA, $locationB] = Location::factory()->count(2)->create(); + [$manufacturerA, $manufacturerB] = Manufacturer::factory()->count(2)->create(); + [$supplierA, $supplierB] = Supplier::factory()->count(2)->create(); + + $accessory = Accessory::factory()->create([ + 'name' => 'A Name to Change', + 'qty' => 5, + 'order_number' => 'A12345', + 'purchase_cost' => 99.99, + 'model_number' => 'ABC098', + 'category_id' => $categoryA->id, + 'company_id' => $companyA->id, + 'location_id' => $locationA->id, + 'manufacturer_id' => $manufacturerA->id, + 'supplier_id' => $supplierA->id, + ]); + + $this->actingAsForApi(User::factory()->editAccessories()->create()) + ->patchJson(route('api.accessories.update', $accessory), [ + 'name' => 'A New Name', + 'qty' => 10, + 'order_number' => 'B54321', + 'purchase_cost' => 199.99, + 'model_number' => 'XYZ123', + 'category_id' => $categoryB->id, + 'company_id' => $companyB->id, + 'location_id' => $locationB->id, + 'manufacturer_id' => $manufacturerB->id, + 'supplier_id' => $supplierB->id, + ]) + ->assertOk(); + + $accessory = $accessory->fresh(); + $this->assertEquals('A New Name', $accessory->name); + $this->assertEquals(10, $accessory->qty); + $this->assertEquals('B54321', $accessory->order_number); + $this->assertEquals(199.99, $accessory->purchase_cost); + $this->assertEquals('XYZ123', $accessory->model_number); + $this->assertEquals($categoryB->id, $accessory->category_id); + $this->assertEquals($companyB->id, $accessory->company_id); + $this->assertEquals($locationB->id, $accessory->location_id); + $this->assertEquals($manufacturerB->id, $accessory->manufacturer_id); + $this->assertEquals($supplierB->id, $accessory->supplier_id); + } } From d639d6fbc1467ce8f231c73507ec371f4c705fc5 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 19 Sep 2024 12:21:54 -0700 Subject: [PATCH 21/86] Add tests for accessory select list endpoint --- .../Api/AccessoriesForSelectListTest.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/Feature/Accessories/Api/AccessoriesForSelectListTest.php diff --git a/tests/Feature/Accessories/Api/AccessoriesForSelectListTest.php b/tests/Feature/Accessories/Api/AccessoriesForSelectListTest.php new file mode 100644 index 0000000000..f2c2185edc --- /dev/null +++ b/tests/Feature/Accessories/Api/AccessoriesForSelectListTest.php @@ -0,0 +1,59 @@ +count(2)->create(); + + $accessoryA = Accessory::factory()->for($companyA)->create(); + $accessoryB = Accessory::factory()->for($companyB)->create(); + + $superuser = User::factory()->superuser()->create(); + $userInCompanyA = $companyA->users()->save(User::factory()->viewAccessories()->make()); + $userInCompanyB = $companyB->users()->save(User::factory()->viewAccessories()->make()); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($userInCompanyA) + ->getJson(route('api.accessories.selectlist')) + ->assertOk() + ->assertJsonPath('total_count', 1) + ->assertResponseContainsInResults($accessoryA) + ->assertResponseDoesNotContainInResults($accessoryB); + + $this->actingAsForApi($userInCompanyB) + ->getJson(route('api.accessories.selectlist')) + ->assertOk() + ->assertJsonPath('total_count', 1) + ->assertResponseDoesNotContainInResults($accessoryA) + ->assertResponseContainsInResults($accessoryB); + + $this->actingAsForApi($superuser) + ->getJson(route('api.accessories.selectlist')) + ->assertOk() + ->assertJsonPath('total_count', 2) + ->assertResponseContainsInResults($accessoryA) + ->assertResponseContainsInResults($accessoryB); + } + + public function testCanGetAccessoriesForSelectList() + { + [$accessoryA, $accessoryB] = Accessory::factory()->count(2)->create(); + + $this->actingAsForApi(User::factory()->viewAccessories()->create()) + ->getJson(route('api.accessories.selectlist')) + ->assertOk() + ->assertJsonPath('total_count', 2) + ->assertResponseContainsInResults($accessoryA) + ->assertResponseContainsInResults($accessoryB); + } +} From 0b3f458561370fd6c825cc756c2de633c77326df Mon Sep 17 00:00:00 2001 From: bryanlopezinc Date: Mon, 30 Sep 2024 12:42:41 +0100 Subject: [PATCH 22/86] Added tests for Import feature --- app/Models/Asset.php | 14 +- database/factories/ImportFactory.php | 146 +++++ database/factories/UserFactory.php | 3 + .../Importing/Api/ImportAccessoriesTest.php | 426 +++++++++++++ .../Importing/Api/ImportAssetsTest.php | 601 ++++++++++++++++++ .../Importing/Api/ImportComponentsTest.php | 309 +++++++++ .../Importing/Api/ImportConsumablesTest.php | 309 +++++++++ .../Importing/Api/ImportDataTestCase.php | 36 ++ .../Importing/Api/ImportLicenseTest.php | 360 +++++++++++ .../Feature/Importing/Api/ImportUsersTest.php | 340 ++++++++++ .../AccessoriesImportFileBuilder.php | 74 +++ .../Importing/AssetsImportFileBuilder.php | 92 +++ .../Importing/ComponentsImportFileBuilder.php | 65 ++ .../ConsumablesImportFileBuilder.php | 65 ++ tests/Support/Importing/FileBuilder.php | 249 ++++++++ .../Importing/LicensesImportFileBuilder.php | 86 +++ .../Importing/UsersImportFileBuilder.php | 65 ++ 17 files changed, 3233 insertions(+), 7 deletions(-) create mode 100644 database/factories/ImportFactory.php create mode 100644 tests/Feature/Importing/Api/ImportAccessoriesTest.php create mode 100644 tests/Feature/Importing/Api/ImportAssetsTest.php create mode 100644 tests/Feature/Importing/Api/ImportComponentsTest.php create mode 100644 tests/Feature/Importing/Api/ImportConsumablesTest.php create mode 100644 tests/Feature/Importing/Api/ImportDataTestCase.php create mode 100644 tests/Feature/Importing/Api/ImportLicenseTest.php create mode 100644 tests/Feature/Importing/Api/ImportUsersTest.php create mode 100644 tests/Support/Importing/AccessoriesImportFileBuilder.php create mode 100644 tests/Support/Importing/AssetsImportFileBuilder.php create mode 100644 tests/Support/Importing/ComponentsImportFileBuilder.php create mode 100644 tests/Support/Importing/ConsumablesImportFileBuilder.php create mode 100644 tests/Support/Importing/FileBuilder.php create mode 100644 tests/Support/Importing/LicensesImportFileBuilder.php create mode 100644 tests/Support/Importing/UsersImportFileBuilder.php diff --git a/app/Models/Asset.php b/app/Models/Asset.php index aff06b6689..35cea17265 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -43,16 +43,16 @@ class Asset extends Depreciable /** * Run after the checkout acceptance was declined by the user - * + * * @param User $acceptedBy * @param string $signature - */ + */ public function declinedCheckout(User $declinedBy, $signature) { $this->assigned_to = null; $this->assigned_type = null; - $this->accepted = null; - $this->save(); + $this->accepted = null; + $this->save(); } /** @@ -369,7 +369,7 @@ class Asset extends Depreciable if ($this->save()) { if (is_int($admin)) { $checkedOutBy = User::findOrFail($admin); - } elseif (get_class($admin) === \App\Models\User::class) { + } elseif ($admin && get_class($admin) === \App\Models\User::class) { $checkedOutBy = $admin; } else { $checkedOutBy = auth()->user(); @@ -1695,7 +1695,7 @@ class Asset extends Depreciable }); }); } - + /** * THIS CLUNKY BIT IS VERY IMPORTANT @@ -1716,7 +1716,7 @@ class Asset extends Depreciable * assets.location would fail, as that field doesn't exist -- plus we're already searching * against those relationships earlier in this method. * - * - snipe + * - snipe * */ diff --git a/database/factories/ImportFactory.php b/database/factories/ImportFactory.php new file mode 100644 index 0000000000..4fafc96216 --- /dev/null +++ b/database/factories/ImportFactory.php @@ -0,0 +1,146 @@ + + */ +class ImportFactory extends Factory +{ + /** + * @inheritdoc + */ + protected $model = Import::class; + + /** + * @inheritdoc + */ + public function definition() + { + return [ + 'name' => $this->faker->company, + 'file_path' => Str::random().'.csv', + 'filesize' => $this->faker->randomDigitNotNull(), + 'field_map' => null, + ]; + } + + /** + * Create an accessory import type. + * + * @return static + */ + public function accessory() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\AccessoriesImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Accessories"; + $attributes['import_type'] = 'Accessories'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + + /** + * Create an asset import type. + * + * @return static + */ + public function asset() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\AssetsImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Assets"; + $attributes['import_type'] = 'asset'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + + /** + * Create a component import type. + * + * @return static + */ + public function component() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\ComponentsImportFileBuilder::times(); + + $attributes['name'] = "{$attributes['name']} Components"; + $attributes['import_type'] = 'component'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + + /** + * Create a consumable import type. + * + * @return static + */ + public function consumable() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\ConsumablesImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Consumables"; + $attributes['import_type'] = 'consumable'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + + /** + * Create a license import type. + * + * @return static + */ + public function license() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\LicensesImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Licenses"; + $attributes['import_type'] = 'license'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } + + /** + * Create a users import type. + * + * @return static + */ + public function users() + { + return $this->state(function (array $attributes) { + $fileBuilder = Importing\UsersImportFileBuilder::new(); + + $attributes['name'] = "{$attributes['name']} Employees"; + $attributes['import_type'] = 'user'; + $attributes['header_row'] = $fileBuilder->toCsv()[0]; + $attributes['first_row'] = $fileBuilder->firstRow(); + + return $attributes; + }); + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index b375142196..d5ef8093bd 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -7,6 +7,9 @@ use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; use \Auth; +/** + * @extends Factory + */ class UserFactory extends Factory { /** diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php new file mode 100644 index 0000000000..cf7597c314 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -0,0 +1,426 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAccessoryPermissionCanImportAccessories(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->accessory()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importAccessory(): void + { + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => [ + 'redirect_url' => route('accessories.index') + ] + ]); + + $newAccessory = Accessory::query() + ->with(['location', 'category', 'manufacturer', 'supplier', 'company']) + ->where('name', $row['itemName']) + ->sole(); + + $activityLog = Actionlog::query() + ->where('item_type', Accessory::class) + ->where('item_id', $newAccessory->id) + ->sole(); + + $this->assertEquals($activityLog->action_type, 'create'); + $this->assertEquals($activityLog->action_source, 'importer'); + $this->assertEquals($activityLog->company_id, $newAccessory->company->id); + + $this->assertEquals($newAccessory->name, $row['itemName']); + $this->assertEquals($newAccessory->qty, $row['quantity']); + $this->assertEquals($newAccessory->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($newAccessory->purchase_cost, $row['purchaseCost']); + $this->assertEquals($newAccessory->order_number, $row['orderNumber']); + $this->assertEquals($newAccessory->notes, $row['notes']); + $this->assertEquals($newAccessory->category->name, $row['category']); + $this->assertEquals($newAccessory->category->category_type, 'accessory'); + $this->assertEquals($newAccessory->manufacturer->name, $row['manufacturerName']); + $this->assertEquals($newAccessory->supplier->name, $row['supplierName']); + $this->assertEquals($newAccessory->location->name, $row['location']); + $this->assertEquals($newAccessory->company->name, $row['companyName']); + $this->assertEquals($newAccessory->model_number, $row['modelNumber']); + $this->assertFalse($newAccessory->requestable); + $this->assertNull($newAccessory->min_amt); + $this->assertNull($newAccessory->user_id); + } + + #[Test] + public function whenImportFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->definition(); + $row['unknownColumn'] = $this->faker->word; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willFormatDate(): void + { + $importFileBuilder = ImportFileBuilder::new(['purchaseDate' => '2022/10/10']); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $accessory = Accessory::query() + ->where('name', $importFileBuilder->firstRow()['itemName']) + ->sole(['purchase_date']); + + $this->assertEquals($accessory->purchase_date->toDateString(), '2022-10-10'); + } + + #[Test] + public function willNotCreateNewCategoryWhenCategoryExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => Str::random()]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessories = Accessory::query() + ->whereIn('name', $importFileBuilder->pluck('itemName')) + ->get(); + + $this->assertCount(1, $newAccessories->pluck('category_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewAccessoryWhenAccessoryWithNameExists(): void + { + $accessory = AccessoryFactory::new()->create(['name' => Str::random()]); + $importFileBuilder = ImportFileBuilder::times(2)->replace(['itemName' => $accessory->name]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $probablyNewAccessories = Accessory::query() + ->where('name', $importFileBuilder->pluck('itemName')) + ->get(['name']); + + $this->assertCount(1, $probablyNewAccessories); + $this->assertEquals($probablyNewAccessories->first()->name, $accessory->name); + } + + #[Test] + public function willNotCreateNewCompanyWhenCompanyAlreadyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessories = Accessory::query() + ->where('name', $importFileBuilder->pluck('itemName')) + ->get(['company_id']); + + $this->assertCount(1, $newAccessories->pluck('company_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewLocationWhenLocationAlreadyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessories = Accessory::query() + ->where('name', $importFileBuilder->pluck('itemName')) + ->get(['location_id']); + + $this->assertCount(1, $newAccessories->pluck('location_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewManufacturerWhenManufacturerAlreadyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => $this->faker->company]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessories = Accessory::query() + ->where('name', $importFileBuilder->pluck('itemName')) + ->get(['manufacturer_id']); + + $this->assertCount(1, $newAccessories->pluck('manufacturer_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewSupplierWhenSupplierAlreadyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['supplierName' => $this->faker->company]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessories = Accessory::query() + ->where('name', $importFileBuilder->pluck('itemName')) + ->get(['supplier_id']); + + $this->assertCount(1, $newAccessories->pluck('supplier_id')->unique()->all()); + } + + #[Test] + public function whenColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::new()->forget(['minimumAmount', 'purchaseCost', 'purchaseDate']); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAccessory = Accessory::query() + ->where('name', $importFileBuilder->firstRow()['itemName']) + ->sole(); + + $this->assertNull($newAccessory->min_amt); + $this->assertNull($newAccessory->purchase_date); + $this->assertNull($newAccessory->purchase_cost); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::new()->forget(['itemName', 'quantity', 'category']); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + '' => [ + 'Accessory' => [ + 'name' => ['The name field is required.'], + 'qty' => ['The qty field must be at least 1.'], + 'category_id' => ['The category id field is required.'] + ] + ] + ] + ]); + } + + #[Test] + public function updateAccessoryFromImport(): void + { + $accessory = AccessoryFactory::new()->create(['name' => Str::random()])->refresh(); + $importFileBuilder = ImportFileBuilder::new(['itemName' => $accessory->name]); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedAccessory = Accessory::query()->find($accessory->id); + $updatedAttributes = [ + 'name', 'company_id', 'qty', 'purchase_date', 'purchase_cost', + 'order_number', 'notes', 'category_id', 'manufacturer_id', 'supplier_id', + 'location_id', 'model_number', 'updated_at' + ]; + + $this->assertEquals($updatedAccessory->name, $row['itemName']); + $this->assertEquals($row['companyName'], $updatedAccessory->company->name); + $this->assertEquals($updatedAccessory->qty, $row['quantity']); + $this->assertEquals($updatedAccessory->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($updatedAccessory->purchase_cost, $row['purchaseCost']); + $this->assertEquals($updatedAccessory->order_number, $row['orderNumber']); + $this->assertEquals($updatedAccessory->notes, $row['notes']); + $this->assertEquals($updatedAccessory->category->name, $row['category']); + $this->assertEquals($updatedAccessory->category->category_type, 'accessory'); + $this->assertEquals($updatedAccessory->manufacturer->name, $row['manufacturerName']); + $this->assertEquals($updatedAccessory->supplier->name, $row['supplierName']); + $this->assertEquals($updatedAccessory->location->name, $row['location']); + $this->assertEquals($updatedAccessory->model_number, $row['modelNumber']); + + $this->assertEquals( + Arr::except($updatedAccessory->attributesToArray(), $updatedAttributes), + Arr::except($accessory->attributesToArray(), $updatedAttributes), + ); + } + + #[Test] + public function whenImportFileContainsEmptyValues(): void + { + $accessory = AccessoryFactory::new()->create(['name' => Str::random()]); + $accessory->refresh(); + + $importFileBuilder = ImportFileBuilder::new([ + 'companyName' => ' ', + 'purchaseDate' => ' ', + 'purchaseCost' => '', + 'location' => '', + 'companyName' => '', + 'orderNumber' => '', + 'category' => '', + 'quantity' => '', + 'manufacturerName' => '', + 'supplierName' => '', + 'notes' => '', + 'requestAble' => '', + 'minimumAmount' => '', + 'modelNumber' => '' + ]); + + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + $importFileBuilder->firstRow()['itemName'] => [ + 'Accessory' => [ + 'qty' => ['The qty field must be at least 1.'], + 'category_id' => ['The category id field is required.'] + ] + ] + ] + ]); + + $importFileBuilder->replace(['itemName' => $accessory->name]); + + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedAccessory = clone $accessory; + $updatedAccessory->refresh(); + + $this->assertEquals($updatedAccessory->toArray(), $accessory->toArray()); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::new()->definition(); + $row = [ + 'itemName' => $faker['modelNumber'], + 'purchaseDate' => $faker['notes'], + 'purchaseCost' => $faker['location'], + 'location' => $faker['purchaseCost'], + 'companyName' => $faker['orderNumber'], + 'orderNumber' => $faker['companyName'], + 'category' => $faker['manufacturerName'], + 'manufacturerName' => $faker['category'], + 'notes' => $faker['purchaseDate'], + 'minimumAmount' => $faker['supplierName'], + 'modelNumber' => $faker['itemName'], + 'quantity' => $faker['quantity'] + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Item Name' => 'model_number', + 'Purchase Date' => 'notes', + 'Purchase Cost' => 'location', + 'Location' => 'purchase_cost', + 'Company' => 'order_number', + 'Order Number' => 'company', + 'Category' => 'manufacturer', + 'Manufacturer' => 'category', + 'Supplier' => 'min_amt', + 'Notes' => 'purchase_date', + 'Min QTY' => 'supplier', + 'Model Number' => 'item_name', + 'Quantity' => 'quantity' + ] + ])->assertOk(); + + $newAccessory = Accessory::query() + ->with(['location', 'category', 'manufacturer', 'supplier']) + ->where('name', $row['modelNumber']) + ->sole(); + + $this->assertEquals($newAccessory->name, $row['modelNumber']); + $this->assertEquals($newAccessory->model_number, $row['itemName']); + $this->assertEquals($newAccessory->qty, $row['quantity']); + $this->assertEquals($newAccessory->purchase_date->toDateString(), $row['notes']); + $this->assertEquals($newAccessory->purchase_cost, $row['location']); + $this->assertEquals($newAccessory->order_number, $row['companyName']); + $this->assertEquals($newAccessory->notes, $row['purchaseDate']); + $this->assertEquals($newAccessory->category->name, $row['manufacturerName']); + $this->assertEquals($newAccessory->manufacturer->name, $row['category']); + $this->assertEquals($newAccessory->location->name, $row['purchaseCost']); + } +} diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php new file mode 100644 index 0000000000..b7c6298d32 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -0,0 +1,601 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAssetsPermissionCanImportAssets(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->asset()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importAsset(): void + { + Notification::fake(); + + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('hardware.index')] + ]); + + $newAsset = Asset::query() + ->with(['location', 'supplier', 'company', 'assignedAssets', 'defaultLoc', 'assetStatus', 'model.category', 'model.manufacturer']) + ->where('serial', $row['serialNumber']) + ->sole(); + + $assignee = User::query()->find($newAsset->assigned_to, ['id', 'first_name', 'last_name', 'email', 'username']); + + $activityLogs = ActionLog::query() + ->where('item_type', Asset::class) + ->where('item_id', $newAsset->id) + ->get(); + + $this->assertCount(2, $activityLogs); + + $this->assertEquals($activityLogs[0]->action_type, 'checkout'); + $this->assertEquals($activityLogs[0]->item_type, Asset::class); + $this->assertEquals($activityLogs[0]->target_id, $assignee->id); + $this->assertEquals($activityLogs[0]->target_type, User::class); + $this->assertEquals($activityLogs[0]->note, 'Checkout from CSV Importer'); + + $this->assertEquals($activityLogs[1]->action_type, 'create'); + $this->assertNull($activityLogs[1]->target_id); + $this->assertEquals($activityLogs[1]->item_type, Asset::class); + $this->assertNull($activityLogs[1]->note); + $this->assertNull($activityLogs[1]->target_type); + + $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['assigneeFullName']); + $this->assertEquals($assignee->email, $row['assigneeEmail']); + $this->assertEquals($assignee->username, $row['assigneeUsername']); + + $this->assertEquals($newAsset->model->category->name, $row['category']); + $this->assertEquals($newAsset->model->manufacturer->name, $row['manufacturerName']); + $this->assertEquals($newAsset->name, $row['itemName']); + $this->assertEquals($newAsset->asset_tag, $row['tag']); + $this->assertEquals($newAsset->model->name, $row['model']); + $this->assertEquals($newAsset->model->model_number, $row['modelNumber']); + $this->assertEquals($newAsset->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertNull($newAsset->asset_eol_date); + $this->assertEquals(0, $newAsset->eol_explicit); + $this->assertEquals($newAsset->location_id, $newAsset->rtd_location_id); + $this->assertEquals($newAsset->purchase_cost, $row['purchaseCost']); + $this->assertNull($newAsset->order_number); + $this->assertEquals($newAsset->image, ''); + $this->assertNull($newAsset->user_id); + $this->assertEquals($newAsset->physical, 1); + $this->assertEquals($newAsset->assetStatus->name, $row['status']); + $this->assertEquals($newAsset->archived, 0); + $this->assertEquals($newAsset->warranty_months, $row['warrantyInMonths']); + $this->assertNull($newAsset->deprecate); + $this->assertEquals($newAsset->supplier->name, $row['supplierName']); + $this->assertEquals($newAsset->requestable, 0); + $this->assertEquals($newAsset->defaultLoc->name, $row['location']); + $this->assertEquals($newAsset->accepted, null); + $this->assertEquals(Carbon::parse($newAsset->last_checkout)->toDateString(), now()->toDateString()); + $this->assertEquals($newAsset->last_checkin, 0); + $this->assertEquals($newAsset->expected_checkin, 0); + $this->assertEquals($newAsset->company->name, $row['companyName']); + $this->assertEquals($newAsset->assigned_type, User::class); + $this->assertNull($newAsset->last_audit_date); + $this->assertNull($newAsset->next_audit_date); + $this->assertEquals($newAsset->location->name, $row['location']); + $this->assertEquals($newAsset->checkin_counter, 0); + $this->assertEquals($newAsset->checkout_counter, 1); + $this->assertEquals($newAsset->requests_counter, 0); + $this->assertEquals($newAsset->byod, 0); + + //Notes is never read. + //$this->assertEquals($asset->notes, $row['notes']); + + Notification::assertSentTo($assignee, CheckoutAssetNotification::class); + } + + #[Test] + public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->definition(); + $row['unknownColumnInCsvFile'] = 'foo'; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willNotCreateNewAssetWhenAssetWithSameTagAlreadyExists(): void + { + $asset = AssetFactory::new()->create(['asset_tag' => $this->faker->uuid]); + $importFileBuilder = ImportFileBuilder::times(4)->replace(['tag' => $asset->asset_tag]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + '' => [ + 'asset_tag' => [ + 'asset_tag' => [ + "An asset with the asset tag {$asset->asset_tag} already exists and an update was not requested. No change was made." + ] + ] + ] + ] + ]); + + $assetsWithSameTag = Asset::query()->where('asset_tag', $asset->asset_tag)->get(); + + $this->assertCount(1, $assetsWithSameTag); + } + + #[Test] + public function willNotCreateNewCompanyWhenCompanyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(1, $newAssets->pluck('company_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewLocationWhenLocationExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(1, $newAssets->pluck('location_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewSupplierWhenSupplierExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['supplierName' => $this->faker->company]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['supplier_id']); + + $this->assertCount(1, $newAssets->pluck('supplier_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewManufacturerWhenManufacturerExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => $this->faker->company]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->with('model.manufacturer') + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(1, $newAssets->pluck('model.manufacturer_id')->unique()->all()); + } + + #[Test] + public function willNotCreateCategoryWhenCategoryExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->with('model.category') + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(1, $newAssets->pluck('model.category_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewAssetModelWhenAssetModelExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['model' => Str::random()]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAssets = Asset::query() + ->with('model') + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(1, $newAssets->pluck('model.name')->unique()->all()); + } + + #[Test] + public function whenColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::times()->forget([ + 'purchaseCost', + 'purchaseDate', + 'status' + ]); + + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAsset = Asset::query() + ->with(['assetStatus']) + ->where('serial', $importFileBuilder->firstRow()['serialNumber']) + ->sole(); + + $this->assertEquals($newAsset->assetStatus->name, 'Ready to Deploy'); + $this->assertNull($newAsset->purchase_date); + $this->assertNull($newAsset->purchase_cost); + } + + #[Test] + public function willFormatValues(): void + { + $importFileBuilder = ImportFileBuilder::new([ + 'warrantyInMonths' => '3 months', + 'purchaseDate' => '2022/10/10' + ]); + + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAsset = Asset::query() + ->where('serial', $importFileBuilder->firstRow()['serialNumber']) + ->sole(); + + $this->assertEquals($newAsset->warranty_months, 3); + $this->assertEquals($newAsset->purchase_date->toDateString(), '2022-10-10'); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::times(2) + ->forget(['tag']) + ->replace(['model' => '']); + + $rows = $importFileBuilder->all(); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + $rows[0]['itemName'] => [ + "Asset \"{$rows[0]['itemName']}\"" => [ + 'asset_tag' => [ + 'The asset tag field must be at least 1 characters.', + ], + 'model_id' => [ + 'The model id field is required.' + ] + ] + ], + $rows[1]['itemName'] => [ + "Asset \"{$rows[1]['itemName']}\"" => [ + 'asset_tag' => [ + 'The asset tag field must be at least 1 characters.', + ], + 'model_id' => [ + 'The model id field is required.' + ] + ] + ] + ] + ]); + + $newAssets = Asset::query() + ->whereIn('serial', Arr::pluck($rows, 'serialNumber')) + ->get(); + + $this->assertCount(0, $newAssets); + } + + #[Test] + public function updateAssetFromImport(): void + { + $asset = AssetFactory::new()->create()->refresh(); + $importFileBuilder = ImportFileBuilder::times(1)->replace(['tag' => $asset->asset_tag]); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedAsset = Asset::query() + ->with(['location', 'supplier', 'company', 'defaultLoc', 'assetStatus', 'model.category', 'model.manufacturer']) + ->find($asset->id); + + $assignee = User::query()->find($updatedAsset->assigned_to, ['id', 'first_name', 'last_name', 'email', 'username']); + + $updatedAttributes = [ + 'category', 'manufacturer_id', 'name', 'tag', 'model_id', + 'model_number', 'purchase_date', 'purchase_cost', 'warranty_months', 'supplier_id', + 'location_id', 'company_id', 'serial', 'assigned_to', 'status_id', 'rtd_location_id', + 'last_checkout', 'requestable', 'updated_at', 'checkout_counter', 'assigned_type' + ]; + + $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['assigneeFullName']); + $this->assertEquals($assignee->email, $row['assigneeEmail']); + $this->assertEquals($assignee->username, $row['assigneeUsername']); + + $this->assertEquals($updatedAsset->model->category->name, $row['category']); + $this->assertEquals($updatedAsset->model->manufacturer->name, $row['manufacturerName']); + $this->assertEquals($updatedAsset->name, $row['itemName']); + $this->assertEquals($updatedAsset->asset_tag, $row['tag']); + $this->assertEquals($updatedAsset->model->name, $row['model']); + $this->assertEquals($updatedAsset->model->model_number, $row['modelNumber']); + $this->assertEquals($updatedAsset->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($updatedAsset->purchase_cost, $row['purchaseCost']); + $this->assertEquals($updatedAsset->assetStatus->name, $row['status']); + $this->assertEquals($updatedAsset->warranty_months, $row['warrantyInMonths']); + $this->assertEquals($updatedAsset->supplier->name, $row['supplierName']); + $this->assertEquals($updatedAsset->defaultLoc->name, $row['location']); + $this->assertEquals($updatedAsset->company->name, $row['companyName']); + $this->assertEquals($updatedAsset->location->name, $row['location']); + $this->assertEquals($updatedAsset->checkout_counter, 1); + $this->assertEquals($updatedAsset->assigned_type, user::class); + + //RequestAble is always updated regardless of initial value. + //$this->assertEquals($updatedAsset->requestable, $asset->requestable); + + $this->assertEquals( + Arr::except($updatedAsset->attributesToArray(), $updatedAttributes), + Arr::except($asset->attributesToArray(), $updatedAttributes), + ); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::new()->definition(); + $row = [ + 'assigneeFullName' => $faker['supplierName'], + 'assigneeEmail' => $faker['manufacturerName'], + 'assigneeUsername' => $faker['serialNumber'], + 'category' => $faker['location'], + 'companyName' => $faker['purchaseCost'], + 'itemName' => $faker['modelNumber'], + 'location' => $faker['assigneeUsername'], + 'manufacturerName' => $faker['status'], + 'model' => $faker['itemName'], + 'modelNumber' => $faker['category'], + 'notes' => $faker['notes'], + 'purchaseCost' => $faker['model'], + 'purchaseDate' => $faker['companyName'], + 'serialNumber' => $faker['tag'], + 'supplierName' => $faker['purchaseDate'], + 'status' => $faker['warrantyInMonths'], + 'tag' => $faker['assigneeEmail'], + 'warrantyInMonths' => $faker['assigneeFullName'], + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Asset Tag' => 'email', + 'Category' => 'location', + 'Company' => 'purchase_cost', + 'Email' => 'manufacturer', + 'Full Name' => 'supplier', + 'Item Name' => 'model_number', + 'Location' => 'username', + 'Manufacturer' => 'status', + 'Model name' => 'item_name', + 'Model Number' => 'category', + 'Notes' => 'asset_notes', + 'Purchase Cost' => 'asset_model', + 'Purchase Date' => 'company', + 'Serial number' => 'asset_tag', + 'Status' => 'warranty_months', + 'Supplier' => 'purchase_date', + 'Username' => 'serial', + 'Warranty' => 'full_name', + ] + ])->assertOk(); + + $asset = Asset::query() + ->with(['location', 'supplier', 'company', 'assignedAssets', 'defaultLoc', 'assetStatus', 'model.category', 'model.manufacturer']) + ->where('serial', $row['assigneeUsername']) + ->sole(); + + $assignee = User::query()->find($asset->assigned_to, ['id', 'first_name', 'last_name', 'email', 'username']); + + $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['warrantyInMonths']); + $this->assertEquals($assignee->email, $row['tag']); + $this->assertEquals($assignee->username, $row['location']); + + $this->assertEquals($asset->model->category->name, $row['modelNumber']); + $this->assertEquals($asset->model->manufacturer->name, $row['assigneeEmail']); + $this->assertEquals($asset->name, $row['model']); + $this->assertEquals($asset->asset_tag, $row['serialNumber']); + $this->assertEquals($asset->model->name, $row['purchaseCost']); + $this->assertEquals($asset->model->model_number, $row['itemName']); + $this->assertEquals($asset->purchase_date->toDateString(), $row['supplierName']); + $this->assertEquals($asset->purchase_cost, $row['companyName']); + $this->assertEquals($asset->assetStatus->name, $row['manufacturerName']); + $this->assertEquals($asset->warranty_months, $row['status']); + $this->assertEquals($asset->supplier->name, $row['assigneeFullName']); + $this->assertEquals($asset->defaultLoc->name, $row['category']); + $this->assertEquals($asset->company->name, $row['purchaseDate']); + $this->assertEquals($asset->location->name, $row['category']); + $this->assertEquals($asset->notes, $row['notes']); + $this->assertNull($asset->asset_eol_date); + $this->assertEquals(0, $asset->eol_explicit); + $this->assertNull($asset->order_number); + $this->assertEquals($asset->image, ''); + $this->assertNull($asset->user_id); + $this->assertEquals($asset->physical, 1); + $this->assertEquals($asset->archived, 0); + $this->assertNull($asset->deprecate); + $this->assertEquals($asset->requestable, 0); + $this->assertEquals($asset->accepted, null); + $this->assertEquals(Carbon::parse($asset->last_checkout)->toDateString(), now()->toDateString()); + $this->assertEquals($asset->last_checkin, 0); + $this->assertEquals($asset->expected_checkin, 0); + $this->assertEquals($asset->assigned_type, User::class); + $this->assertNull($asset->last_audit_date); + $this->assertNull($asset->next_audit_date); + $this->assertEquals($asset->checkin_counter, 0); + $this->assertEquals($asset->checkout_counter, 1); + $this->assertEquals($asset->requests_counter, 0); + $this->assertEquals($asset->byod, 0); + } + + #[Test] + public function customFields(): void + { + $macAddress = $this->faker->macAddress; + + $row = ImportFileBuilder::new()->definition(); + $row['Mac Address'] = $macAddress; + + $importFileBuilder = new ImportFileBuilder([$row]); + $customField = CustomField::query()->where('name', 'Mac Address')->firstOrNew(); + + if (!$customField->exists) { + $customField = CustomFieldFactory::new()->macAddress()->create(['db_column' => '_snipeit_mac_address_1']); + } + + if ($customField->field_encrypted) { + $customField->field_encrypted = 0; + $customField->save(); + } + + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newAsset = Asset::query()->where('serial', $importFileBuilder->firstRow()['serialNumber'])->sole(); + + $this->assertEquals($newAsset->getAttribute($customField->db_column), $macAddress); + } + + #[Test] + public function willEncryptCustomFields(): void + { + $macAddress = $this->faker->macAddress; + $row = ImportFileBuilder::new()->definition(); + + $row['Mac Address'] = $macAddress; + + $importFileBuilder = new ImportFileBuilder([$row]); + $customField = CustomField::query()->where('name', 'Mac Address')->firstOrNew(); + + if (!$customField->exists) { + $customField = CustomFieldFactory::new()->macAddress()->create(); + } + + if (!$customField->field_encrypted) { + $customField->field_encrypted = 1; + $customField->save(); + } + + $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $asset = Asset::query()->where('serial', $importFileBuilder->firstRow()['serialNumber'])->sole(); + $encryptedMacAddress = $asset->getAttribute($customField->db_column); + + $this->assertNotEquals($encryptedMacAddress, $macAddress); + } +} diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php new file mode 100644 index 0000000000..56c40ba462 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -0,0 +1,309 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAssetsPermissionCanImportComponents(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->component()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importComponents(): void + { + Notification::fake(); + + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('components.index')] + ]); + + $newComponent = Component::query() + ->with(['location', 'category', 'company']) + ->where('name', $row['itemName']) + ->sole(); + + $activityLog = ActionLog::query() + ->where('item_type', Component::class) + ->where('item_id', $newComponent->id) + ->sole(); + + $this->assertEquals($activityLog->action_type, 'create'); + $this->assertEquals($activityLog->action_source, 'importer'); + $this->assertEquals($activityLog->company_id, $newComponent->company->id); + + $this->assertEquals($newComponent->name, $row['itemName']); + $this->assertEquals($newComponent->company->name, $row['companyName']); + $this->assertEquals($newComponent->category->name, $row['category']); + $this->assertEquals($newComponent->location->name, $row['location']); + $this->assertNull($newComponent->supplier_id); + $this->assertEquals($newComponent->qty, $row['quantity']); + $this->assertEquals($newComponent->order_number, $row['orderNumber']); + $this->assertEquals($newComponent->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($newComponent->purchase_cost, $row['purchaseCost']); + $this->assertNull($newComponent->min_amt); + $this->assertEquals($newComponent->serial, $row['serialNumber']); + $this->assertNull($newComponent->image); + $this->assertNull($newComponent->notes); + } + + #[Test] + public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->firstRow(); + $row['unknownColumnInCsvFile'] = 'foo'; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willNotCreateNewComponentWhenComponentWithNameAndSerialNumberExists(): void + { + $component = ComponentFactory::new()->create(); + + $importFileBuilder = ImportFileBuilder::times(4)->replace([ + 'itemName' => $component->name, + 'serialNumber' => $component->serial + ]); + + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $probablyNewComponents = Component::query() + ->where('name', $component->name) + ->where('serial', $component->serial) + ->get(['id']); + + $this->assertCount(1, $probablyNewComponents); + $this->assertEquals($component->id, $probablyNewComponents->sole()->id); + } + + #[Test] + public function willNotCreateNewCompanyWhenCompanyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newComponents = Component::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['company_id']); + + $this->assertCount(1, $newComponents->pluck('company_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewLocationWhenLocationExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newComponents = Component::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['location_id']); + + $this->assertCount(1, $newComponents->pluck('location_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewCategoryWhenCategoryExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newComponents = Component::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['category_id']); + + $this->assertCount(1, $newComponents->pluck('category_id')->unique()->all()); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::new() + ->replace(['category' => '']) + ->forget(['quantity']); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + $row['itemName'] => [ + 'Component' => [ + 'qty' => ['The qty field must be at least 1.'], + 'category_id' => ['The category id field is required.'] + ] + ] + ] + ]); + + $newComponents = Component::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(); + + $this->assertCount(0, $newComponents); + } + + #[Test] + public function updateComponentFromImport(): void + { + $component = ComponentFactory::new()->create(); + $importFileBuilder = ImportFileBuilder::new([ + 'itemName' => $component->name, + 'serialNumber' => $component->serial + ]); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedComponent = Component::query() + ->with(['location', 'category']) + ->where('serial', $row['serialNumber']) + ->sole(); + + $this->assertEquals($updatedComponent->name, $row['itemName']); + $this->assertEquals($updatedComponent->category->name, $row['category']); + $this->assertEquals($updatedComponent->location->name, $row['location']); + $this->assertEquals($updatedComponent->supplier_id, $component->supplier_id); + $this->assertEquals($updatedComponent->qty, $row['quantity']); + $this->assertEquals($updatedComponent->order_number, $row['orderNumber']); + $this->assertEquals($updatedComponent->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($updatedComponent->purchase_cost, $row['purchaseCost']); + $this->assertEquals($updatedComponent->min_amt, $component->min_amt); + $this->assertEquals($updatedComponent->serial, $row['serialNumber']); + $this->assertEquals($updatedComponent->image, $component->image); + $this->assertEquals($updatedComponent->notes, $component->notes); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::new()->definition(); + $row = [ + 'category' => $faker['serialNumber'], + 'companyName' => $faker['quantity'], + 'itemName' => $faker['purchaseDate'], + 'location' => $faker['purchaseCost'], + 'orderNumber' => $faker['orderNumber'], + 'purchaseCost' => $faker['category'], + 'purchaseDate' => $faker['companyName'], + 'quantity' => $faker['itemName'], + 'serialNumber' => $faker['location'] + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Category' => 'serial', + 'Company' => 'quantity', + 'item Name' => 'purchase_date', + 'Location' => 'purchase_cost', + 'Order Number' => 'order_number', + 'Purchase Cost' => 'category', + 'Purchase Date' => 'company', + 'Quantity' => 'item_name', + 'Serial number' => 'location', + ] + ])->assertOk(); + + $newComponent = Component::query() + ->with(['location', 'category']) + ->where('serial', $importFileBuilder->firstRow()['category']) + ->sole(); + + $this->assertEquals($newComponent->name, $row['quantity']); + $this->assertEquals($newComponent->category->name, $row['purchaseCost']); + $this->assertEquals($newComponent->location->name, $row['serialNumber']); + $this->assertNull($newComponent->supplier_id); + $this->assertEquals($newComponent->qty, $row['companyName']); + $this->assertEquals($newComponent->order_number, $row['orderNumber']); + $this->assertEquals($newComponent->purchase_date->toDateString(), $row['itemName']); + $this->assertEquals($newComponent->purchase_cost, $row['location']); + $this->assertNull($newComponent->min_amt); + $this->assertNull($newComponent->image); + $this->assertNull($newComponent->notes); + } +} diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php new file mode 100644 index 0000000000..7591ee9711 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -0,0 +1,309 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAssetsPermissionCanImportConsumables(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->consumable()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importConsumables(): void + { + Notification::fake(); + + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('consumables.index')] + ]); + + $newConsumable = Consumable::query() + ->with(['location', 'category', 'company']) + ->where('name', $row['itemName']) + ->sole(); + + $activityLog = ActivityLog::query() + ->where('item_type', Consumable::class) + ->where('item_id', $newConsumable->id) + ->sole(); + + $this->assertEquals($activityLog->action_type, 'create'); + $this->assertEquals($activityLog->action_source, 'importer'); + $this->assertEquals($activityLog->company_id, $newConsumable->company->id); + + $this->assertEquals($newConsumable->name, $row['itemName']); + $this->assertEquals($newConsumable->category->name, $row['category']); + $this->assertEquals($newConsumable->location->name, $row['location']); + $this->assertEquals($newConsumable->company->name, $row['companyName']); + $this->assertNull($newConsumable->supplier_id); + $this->assertFalse($newConsumable->requestable); + $this->assertNull($newConsumable->image); + $this->assertEquals($newConsumable->order_number, $row['orderNumber']); + $this->assertEquals($newConsumable->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($newConsumable->purchase_cost, $row['purchaseCost']); + $this->assertNull($newConsumable->min_amt); + $this->assertEquals($newConsumable->model_number, ''); + $this->assertNull($newConsumable->item_number); + $this->assertNull($newConsumable->manufacturer_id); + $this->assertNull($newConsumable->notes); + } + + #[Test] + public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->definition(); + $row['unknownColumnInCsvFile'] = 'foo'; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willNotCreateNewConsumableWhenConsumableNameAlreadyExist(): void + { + $consumable = ConsumableFactory::new()->create(['name' => Str::random()]); + $importFileBuilder = ImportFileBuilder::new(['itemName' => $consumable->name]); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $probablyNewConsumables = Consumable::query() + ->where('name', $consumable->name) + ->get(); + + $this->assertCount(1, $probablyNewConsumables); + $this->assertEquals($consumable->id, $probablyNewConsumables->sole()->id); + } + + #[Test] + public function willNotCreateNewCompanyWhenCompanyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newConsumables = Consumable::query() + ->whereIn('name', $importFileBuilder->pluck('itemName')) + ->get(['company_id']); + + $this->assertCount(1, $newConsumables->pluck('company_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewLocationWhenLocationExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newConsumables = Consumable::query() + ->whereIn('name', $importFileBuilder->pluck('itemName')) + ->get(['location_id']); + + $this->assertCount(1, $newConsumables->pluck('location_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewCategoryWhenCategoryExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => Str::random()]); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newConsumables = Consumable::query() + ->whereIn('name', $importFileBuilder->pluck('itemName')) + ->get(['category_id']); + + $this->assertCount(1, $newConsumables->pluck('category_id')->unique()->all()); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::new(['category' => ''])->forget(['quantity', 'name']); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + $row['itemName'] => [ + 'Consumable' => [ + 'category_id' => ['The category id field is required.'] + ] + ] + ] + ]); + + $newConsumables = Consumable::query() + ->whereIn('name', $importFileBuilder->pluck('itemName')) + ->get(['id']); + + $this->assertCount(0, $newConsumables); + } + + #[Test] + public function updateConsumableFromImport(): void + { + $consumable = ConsumableFactory::new()->create(['name' => Str::random()]); + $importFileBuilder = ImportFileBuilder::new(['itemName' => $consumable->name]); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedConsumable = Consumable::query() + ->with(['location', 'category', 'company']) + ->where('name', $importFileBuilder->firstRow()['itemName']) + ->sole(); + + $this->assertEquals($updatedConsumable->name, $row['itemName']); + $this->assertEquals($updatedConsumable->category->name, $row['category']); + $this->assertEquals($updatedConsumable->location->name, $row['location']); + $this->assertEquals($updatedConsumable->company->name, $row['companyName']); + $this->assertEquals($updatedConsumable->order_number, $row['orderNumber']); + $this->assertEquals($updatedConsumable->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($updatedConsumable->purchase_cost, $row['purchaseCost']); + + $this->assertEquals($consumable->supplier_id, $updatedConsumable->supplier_id); + $this->assertEquals($consumable->requestable, $updatedConsumable->requestable); + $this->assertEquals($consumable->min_amt, $updatedConsumable->min_amt); + $this->assertEquals($consumable->model_number, $updatedConsumable->model_number); + $this->assertEquals($consumable->item_number, $updatedConsumable->item_number); + $this->assertEquals($consumable->manufacturer_id, $updatedConsumable->manufacturer_id); + $this->assertEquals($consumable->notes, $updatedConsumable->notes); + $this->assertEquals($consumable->item_number, $updatedConsumable->item_number); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::new()->definition(); + $row = [ + 'category' => $faker['supplier'], + 'companyName' => $faker['quantity'], + 'itemName' => $faker['purchaseDate'], + 'location' => $faker['purchaseCost'], + 'orderNumber' => $faker['orderNumber'], + 'purchaseCost' => $faker['location'], + 'purchaseDate' => $faker['companyName'], + 'quantity' => $faker['itemName'], + 'supplier' => $faker['category'] + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Category' => 'supplier', + 'Company' => 'quantity', + 'item Name' => 'purchase_date', + 'Location' => 'purchase_cost', + 'Order Number' => 'order_number', + 'Purchase Cost' => 'location', + 'Purchase Date' => 'company', + 'Quantity' => 'item_name', + 'Supplier' => 'category', + ] + ])->assertOk(); + + $newConsumable = Consumable::query() + ->with(['location', 'category', 'company']) + ->where('name', $importFileBuilder->firstRow()['quantity']) + ->sole(); + + $this->assertEquals($newConsumable->category->name, $row['supplier']); + $this->assertEquals($newConsumable->location->name, $row['purchaseCost']); + $this->assertEquals($newConsumable->company->name, $row['purchaseDate']); + $this->assertEquals($newConsumable->qty, $row['companyName']); + $this->assertEquals($newConsumable->name, $row['quantity']); + $this->assertNull($newConsumable->supplier_id); + $this->assertFalse($newConsumable->requestable); + $this->assertNull($newConsumable->image); + $this->assertEquals($newConsumable->order_number, $row['orderNumber']); + $this->assertEquals($newConsumable->purchase_date->toDateString(), $row['itemName']); + $this->assertEquals($newConsumable->purchase_cost, $row['location']); + $this->assertNull($newConsumable->min_amt); + $this->assertEquals($newConsumable->model_number, ''); + $this->assertNull($newConsumable->item_number); + $this->assertNull($newConsumable->manufacturer_id); + $this->assertNull($newConsumable->notes); + } +} diff --git a/tests/Feature/Importing/Api/ImportDataTestCase.php b/tests/Feature/Importing/Api/ImportDataTestCase.php new file mode 100644 index 0000000000..ac39fab677 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportDataTestCase.php @@ -0,0 +1,36 @@ +postJson(route('api.imports.importFile', $parameters), $parameters); + } + + /** + * @todo Add more permissions. + */ + public static function permissionsTestData(): array + { + return [ + '`admin`' => ['admin'], + '`reports.view`' => ['reports.view'], + 'only `assets` permission' => [ + 'assets.view', + 'assets.create', + 'assets.edit', + 'assets.delete', + 'assets.checkout', + 'assets.checkin', + 'assets.audit', + 'assets.view.requestable', + 'assets.view.encrypted_custom_fields' + ] + ]; + } +} diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php new file mode 100644 index 0000000000..a5147d55ae --- /dev/null +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -0,0 +1,360 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAssetsPermissionCanImportLicenses(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->license()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importLicenses(): void + { + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('licenses.index')] + ]); + + $newLicense = License::query() + ->withCasts(['reassignable' => 'bool']) + ->with(['category', 'company', 'manufacturer', 'supplier']) + ->where('serial', $row['serialNumber']) + ->sole(); + + $activityLogs = ActivityLog::query() + ->where('item_type', License::class) + ->where('item_id', $newLicense->id) + ->get(); + + $this->assertCount(2, $activityLogs); + + $this->assertEquals($newLicense->name, $row['licenseName']); + $this->assertEquals($newLicense->serial, $row['serialNumber']); + $this->assertEquals($newLicense->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($newLicense->purchase_cost, $row['purchaseCost']); + $this->assertEquals($newLicense->order_number, $row['orderNumber']); + $this->assertEquals($newLicense->seats, $row['seats']); + $this->assertEquals($newLicense->notes, $row['notes']); + $this->assertEquals($newLicense->license_name, $row['licensedToName']); + $this->assertEquals($newLicense->license_email, $row['licensedToEmail']); + $this->assertEquals($newLicense->supplier->name, $row['supplierName']); + $this->assertEquals($newLicense->company->name, $row['companyName']); + $this->assertEquals($newLicense->category->name, $row['category']); + $this->assertEquals($newLicense->expiration_date->toDateString(), $row['expirationDate']); + $this->assertEquals($newLicense->maintained, $row['isMaintained'] === 'TRUE'); + $this->assertEquals($newLicense->reassignable, $row['isReassignAble'] === 'TRUE'); + $this->assertEquals($newLicense->purchase_order, ''); + $this->assertNull($newLicense->depreciation_id); + $this->assertNull($newLicense->termination_date); + $this->assertNull($newLicense->deprecate); + $this->assertNull($newLicense->min_amt); + } + + #[Test] + public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->definition(); + $row['unknownColumnInCsvFile'] = 'foo'; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willNotCreateNewLicenseWhenNameAndSerialNumberAlreadyExist(): void + { + $license = LicenseFactory::new()->create(); + + $importFileBuilder = ImportFileBuilder::times(4)->replace([ + 'itemName' => $license->name, + 'serialNumber' => $license->serial + ]); + + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $probablyNewLicenses = License::query() + ->where('name', $license->name) + ->where('serial', $license->serial) + ->get(); + + $this->assertCount(1, $probablyNewLicenses); + } + + #[Test] + public function formatAttributes(): void + { + $importFileBuilder = ImportFileBuilder::new([ + 'expirationDate' => '2022/10/10' + ]); + + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newLicense = License::query() + ->where('serial', $importFileBuilder->firstRow()['serialNumber']) + ->sole(); + + $this->assertEquals($newLicense->expiration_date->toDateString(), '2022-10-10'); + } + + #[Test] + public function willNotCreateNewCompanyWhenCompanyExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newLicenses = License::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['company_id']); + + $this->assertCount(1, $newLicenses->pluck('company_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewManufacturerWhenManufacturerExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => Str::random()]); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newLicenses = License::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['manufacturer_id']); + + $this->assertCount(1, $newLicenses->pluck('manufacturer_id')->unique()->all()); + } + + #[Test] + public function willNotCreateNewCategoryWhenCategoryExists(): void + { + $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newLicenses = License::query() + ->whereIn('serial', $importFileBuilder->pluck('serialNumber')) + ->get(['category_id']); + + $this->assertCount(1, $newLicenses->pluck('category_id')->unique()->all()); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::times() + ->replace(['name' => '']) + ->forget(['seats']); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + $row['licenseName'] => [ + "License \"{$row['licenseName']}\"" => [ + 'seats' => ['The seats field is required.'], + ] + ] + ] + ]); + + $newLicenses = License::query() + ->where('serial', $row['serialNumber']) + ->get(); + + $this->assertCount(0, $newLicenses); + } + + #[Test] + public function updateLicenseFromImport(): void + { + $license = LicenseFactory::new()->create(); + $importFileBuilder = ImportFileBuilder::new([ + 'licenseName' => $license->name, + 'serialNumber' => $license->serial + ]); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedLicense = License::query() + ->with(['manufacturer', 'category', 'supplier']) + ->where('serial', $row['serialNumber']) + ->sole(); + + $this->assertEquals($updatedLicense->name, $row['licenseName']); + $this->assertEquals($updatedLicense->serial, $row['serialNumber']); + $this->assertEquals($updatedLicense->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($updatedLicense->purchase_cost, $row['purchaseCost']); + $this->assertEquals($updatedLicense->order_number, $row['orderNumber']); + $this->assertEquals($updatedLicense->seats, $row['seats']); + $this->assertEquals($updatedLicense->notes, $row['notes']); + $this->assertEquals($updatedLicense->license_name, $row['licensedToName']); + $this->assertEquals($updatedLicense->license_email, $row['licensedToEmail']); + $this->assertEquals($updatedLicense->supplier->name, $row['supplierName']); + $this->assertEquals($updatedLicense->company->name, $row['companyName']); + $this->assertEquals($updatedLicense->category->name, $row['category']); + $this->assertEquals($updatedLicense->expiration_date->toDateString(), $row['expirationDate']); + $this->assertEquals($updatedLicense->maintained, $row['isMaintained'] === 'TRUE'); + $this->assertEquals($updatedLicense->reassignable, $row['isReassignAble'] === 'TRUE'); + $this->assertEquals($updatedLicense->purchase_order, $license->purchase_order); + $this->assertEquals($updatedLicense->depreciation_id, $license->depreciation_id); + $this->assertEquals($updatedLicense->termination_date, $license->termination_date); + $this->assertEquals($updatedLicense->deprecate, $license->deprecate); + $this->assertEquals($updatedLicense->min_amt, $license->min_amt); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::times()->definition(); + $row = [ + 'category' => $faker['supplierName'], + 'companyName' => $faker['serialNumber'], + 'expirationDate' => $faker['seats'], + 'isMaintained' => $faker['purchaseDate'], + 'isReassignAble' => $faker['purchaseCost'], + 'licensedToName' => $faker['orderNumber'], + 'licensedToEmail' => $faker['notes'], + 'licenseName' => $faker['licenseName'], + 'manufacturerName' => $faker['category'], + 'notes' => $faker['companyName'], + 'orderNumber' => $faker['expirationDate'], + 'purchaseCost' => $faker['isMaintained'], + 'purchaseDate' => $faker['isReassignAble'], + 'seats' => $faker['licensedToName'], + 'serialNumber' => $faker['licensedToEmail'], + 'supplierName' => $faker['manufacturerName'] + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Category' => 'supplier', + 'Company' => 'serial', + 'expiration date' => 'seats', + 'maintained' => 'purchase_date', + 'reassignable' => 'purchase_cost', + 'Licensed To Name' => 'order_number', + 'Licensed To Email' => 'notes', + 'licenseName' => 'name', + 'manufacturer' => 'category', + 'Notes' => 'company', + 'Serial number' => 'license_email', + 'Order Number' => 'expiration_date', + 'purchase Cost' => 'maintained', + 'purchase Date' => 'reassignable', + 'seats' => 'license_name', + 'supplier' => 'manufacturer' + ] + ])->assertOk(); + + $newLicense = License::query() + ->with(['category', 'company', 'manufacturer', 'supplier']) + ->where('serial', $row['companyName']) + ->sole(); + + $this->assertEquals($newLicense->name, $row['licenseName']); + $this->assertEquals($newLicense->serial, $row['companyName']); + $this->assertEquals($newLicense->purchase_date->toDateString(), $row['isMaintained']); + $this->assertEquals($newLicense->purchase_cost, $row['isReassignAble']); + $this->assertEquals($newLicense->order_number, $row['licensedToName']); + $this->assertEquals($newLicense->seats, $row['expirationDate']); + $this->assertEquals($newLicense->notes, $row['licensedToEmail']); + $this->assertEquals($newLicense->license_name, $row['seats']); + $this->assertEquals($newLicense->license_email, $row['serialNumber']); + $this->assertEquals($newLicense->supplier->name, $row['category']); + $this->assertEquals($newLicense->company->name, $row['notes']); + $this->assertEquals($newLicense->category->name, $row['manufacturerName']); + $this->assertEquals($newLicense->expiration_date->toDateString(), $row['orderNumber']); + $this->assertEquals($newLicense->maintained, $row['purchaseCost'] === 'TRUE'); + $this->assertEquals($newLicense->reassignable, $row['purchaseDate'] === 'TRUE'); + $this->assertEquals($newLicense->purchase_order, ''); + $this->assertNull($newLicense->depreciation_id); + $this->assertNull($newLicense->termination_date); + $this->assertNull($newLicense->deprecate); + $this->assertNull($newLicense->min_amt); + } +} diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php new file mode 100644 index 0000000000..4415da3f12 --- /dev/null +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -0,0 +1,340 @@ +map(fn (string $permission) => [$permission => '1']) + ->toJson(); + + $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + + $this->importFileResponse(['import' => 44])->assertForbidden(); + } + + #[Test] + public function userWithImportAssetsPermissionCanImportUsers(): void + { + $this->actingAsForApi(UserFactory::new()->canImport()->create()); + + $import = ImportFactory::new()->users()->create(); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function importUsers(): void + { + Notification::fake(); + + $importFileBuilder = ImportFileBuilder::new(); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'send-welcome' => 1]) + ->assertOk() + ->assertExactJson([ + 'payload' => null, + 'status' => 'success', + 'messages' => ['redirect_url' => route('users.index')] + ]); + + $newUser = User::query() + ->with(['company', 'location']) + ->where('username', $row['username']) + ->sole(); + + Notification::assertNothingSent(); + + $this->assertEquals($newUser->email, $row['email']); + $this->assertEquals($newUser->first_name, $row['firstName']); + $this->assertEquals($newUser->last_name, $row['lastName']); + $this->assertEquals($newUser->employee_num, $row['employeeNumber']); + $this->assertEquals($newUser->company->name, $row['companyName']); + $this->assertEquals($newUser->location->name, $row['location']); + $this->assertEquals($newUser->phone, $row['phoneNumber']); + $this->assertEquals($newUser->jobtitle, $row['position']); + $this->assertTrue(Hash::isHashed($newUser->password)); + $this->assertEquals($newUser->website, ''); + $this->assertEquals($newUser->country, ''); + $this->assertEquals($newUser->address, ''); + $this->assertEquals($newUser->city, ''); + $this->assertEquals($newUser->state, ''); + $this->assertEquals($newUser->zip, ''); + $this->assertNull($newUser->permissions); + $this->assertNull($newUser->avatar); + $this->assertNull($newUser->notes); + $this->assertNull($newUser->skin); + $this->assertNull($newUser->department_id); + $this->assertNull($newUser->two_factor_secret); + $this->assertNull($newUser->idap_import); + $this->assertEquals($newUser->locale, 'en-US'); + $this->assertEquals($newUser->show_in_list, 1); + $this->assertEquals($newUser->two_factor_enrolled, 0); + $this->assertEquals($newUser->two_factor_optin, 0); + $this->assertEquals($newUser->remote, 0); + $this->assertEquals($newUser->autoassign_licenses, 0); + $this->assertEquals($newUser->vip, 0); + $this->assertEquals($newUser->enable_sounds, 0); + $this->assertEquals($newUser->enable_confetti, 0); + $this->assertNull($newUser->created_by); + $this->assertNull($newUser->start_date); + $this->assertNull($newUser->end_date); + $this->assertNull($newUser->scim_externalid); + $this->assertNull($newUser->manager_id); + $this->assertNull($newUser->activation_code); + $this->assertNull($newUser->last_login); + $this->assertNull($newUser->persist_code); + $this->assertNull($newUser->reset_password_code); + $this->assertEquals($newUser->activated, 0); + } + + #[Test] + public function willIgnoreUnknownColumnsWhenFileContainsUnknownColumns(): void + { + $row = ImportFileBuilder::new()->definition(); + $row['unknownColumnInCsvFile'] = 'foo'; + + $importFileBuilder = new ImportFileBuilder([$row]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->importFileResponse(['import' => $import->id])->assertOk(); + } + + #[Test] + public function willNotCreateNewUserWhenUserWithUserNameAlreadyExist(): void + { + $user = UserFactory::new()->create(['username' => Str::random()]); + $importFileBuilder = ImportFileBuilder::times(4)->replace(['username' => $user->username]); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $probablyNewUsers = User::query() + ->where('username', $user->username) + ->get(); + + $this->assertCount(1, $probablyNewUsers); + } + + #[Test] + public function willGenerateUsernameWhenUsernameFieldIsMissing(): void + { + $importFileBuilder = ImportFileBuilder::new()->forget('username'); + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id])->assertOk(); + + $newUser = User::query() + ->where('email', $row['email']) + ->sole(); + + $generatedUsername = User::generateFormattedNameFromFullName("{$row['firstName']} {$row['lastName']}")['username']; + + $this->assertEquals($newUser->username, $generatedUsername); + } + + #[Test] + public function willUpdateLocationOfAllAssetsAssignedToUser(): void + { + $user = UserFactory::new()->create(['username' => Str::random()]); + $assetsAssignedToUser = AssetFactory::new()->create(['assigned_to' => $user->id, 'assigned_type' => User::class]); + $importFileBuilder = ImportFileBuilder::new(['username' => $user->username]); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $userLocation = Location::query()->where('name', $importFileBuilder->firstRow()['location'])->sole(['id']); + + $this->assertEquals( + $assetsAssignedToUser->refresh()->location_id, + $userLocation->id + ); + } + + #[Test] + public function whenRequiredColumnsAreMissingInImportFile(): void + { + $importFileBuilder = ImportFileBuilder::new(['firstName' => ''])->forget(['username']); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse(['import' => $import->id]) + ->assertInternalServerError() + ->assertExactJson([ + 'status' => 'import-errors', + 'payload' => null, + 'messages' => [ + '' => [ + 'User' => [ + 'first_name' => ['The first name field is required.'], + ] + ] + ] + ]); + + $newUsers = User::query() + ->where('email', $importFileBuilder->firstRow()['email']) + ->get(); + + $this->assertCount(0, $newUsers); + } + + #[Test] + public function updateUserFromImport(): void + { + $user = UserFactory::new()->create(['username' => Str::random()])->refresh(); + $importFileBuilder = ImportFileBuilder::new(['username' => $user->username]); + + $row = $importFileBuilder->firstRow(); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); + + $updatedUser = User::query()->with(['company', 'location'])->find($user->id); + $updatedAttributes = [ + 'first_name', 'email', 'last_name', 'employee_num', 'company', + 'location_id', 'company_id', 'updated_at', 'phone', 'jobtitle' + ]; + + $this->assertEquals($updatedUser->email, $row['email']); + $this->assertEquals($updatedUser->first_name, $row['firstName']); + $this->assertEquals($updatedUser->last_name, $row['lastName']); + $this->assertEquals($updatedUser->employee_num, $row['employeeNumber']); + $this->assertEquals($updatedUser->company->name, $row['companyName']); + $this->assertEquals($updatedUser->location->name, $row['location']); + $this->assertEquals($updatedUser->phone, $row['phoneNumber']); + $this->assertEquals($updatedUser->jobtitle, $row['position']); + $this->assertTrue(Hash::isHashed($updatedUser->password)); + + $this->assertEquals( + Arr::except($updatedUser->attributesToArray(), $updatedAttributes), + Arr::except($user->attributesToArray(), $updatedAttributes), + ); + } + + #[Test] + public function customColumnMapping(): void + { + $faker = ImportFileBuilder::new()->definition(); + $row = [ + 'companyName' => $faker['username'], + 'email' => $faker['position'], + 'employeeNumber' => $faker['phoneNumber'], + 'firstName' => $faker['location'], + 'lastName' => $faker['lastName'], + 'location' => $faker['firstName'], + 'phoneNumber' => $faker['employeeNumber'], + 'position' => $faker['email'], + 'username' => $faker['companyName'], + ]; + + $importFileBuilder = new ImportFileBuilder([$row]); + $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + + $this->actingAsForApi(UserFactory::new()->superuser()->create()); + + $this->importFileResponse([ + 'import' => $import->id, + 'column-mappings' => [ + 'Company' => 'username', + 'email' => 'jobtitle', + 'Employee Number' => 'phone_number', + 'First Name' => 'location', + 'Last Name' => 'last_name', + 'Location' => 'first_name', + 'Phone Number' => 'employee_num', + 'Job Title' => 'email', + 'Username' => 'company', + ] + ])->assertOk(); + + $newUser = User::query() + ->with(['company', 'location']) + ->where('username', $row['companyName']) + ->sole(); + + $this->assertEquals($newUser->email, $row['position']); + $this->assertEquals($newUser->first_name, $row['location']); + $this->assertEquals($newUser->last_name, $row['lastName']); + $this->assertEquals($newUser->jobtitle, $row['email']); + $this->assertEquals($newUser->employee_num, $row['phoneNumber']); + $this->assertEquals($newUser->company->name, $row['username']); + $this->assertEquals($newUser->location->name, $row['firstName']); + $this->assertEquals($newUser->phone, $row['employeeNumber']); + $this->assertTrue(Hash::isHashed($newUser->password)); + $this->assertEquals($newUser->website, ''); + $this->assertEquals($newUser->country, ''); + $this->assertEquals($newUser->address, ''); + $this->assertEquals($newUser->city, ''); + $this->assertEquals($newUser->state, ''); + $this->assertEquals($newUser->zip, ''); + $this->assertNull($newUser->permissions); + $this->assertNull($newUser->avatar); + $this->assertNull($newUser->notes); + $this->assertNull($newUser->skin); + $this->assertNull($newUser->department_id); + $this->assertNull($newUser->two_factor_secret); + $this->assertNull($newUser->idap_import); + $this->assertEquals($newUser->locale, 'en-US'); + $this->assertEquals($newUser->show_in_list, 1); + $this->assertEquals($newUser->two_factor_enrolled, 0); + $this->assertEquals($newUser->two_factor_optin, 0); + $this->assertEquals($newUser->remote, 0); + $this->assertEquals($newUser->autoassign_licenses, 0); + $this->assertEquals($newUser->vip, 0); + $this->assertEquals($newUser->enable_sounds, 0); + $this->assertEquals($newUser->enable_confetti, 0); + $this->assertNull($newUser->created_by); + $this->assertNull($newUser->start_date); + $this->assertNull($newUser->end_date); + $this->assertNull($newUser->scim_externalid); + $this->assertNull($newUser->manager_id); + $this->assertNull($newUser->activation_code); + $this->assertNull($newUser->last_login); + $this->assertNull($newUser->persist_code); + $this->assertNull($newUser->reset_password_code); + $this->assertEquals($newUser->activated, 0); + } +} diff --git a/tests/Support/Importing/AccessoriesImportFileBuilder.php b/tests/Support/Importing/AccessoriesImportFileBuilder.php new file mode 100644 index 0000000000..488c91fdc4 --- /dev/null +++ b/tests/Support/Importing/AccessoriesImportFileBuilder.php @@ -0,0 +1,74 @@ + + */ +class AccessoriesImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'category' => 'Category', + 'companyName' => 'Company', + 'itemName' => 'Item Name', + 'location' => 'Location', + 'manufacturerName' => 'Manufacturer', + 'modelNumber' => 'Model Number', + 'notes' => 'Notes', + 'orderNumber' => 'Order Number', + 'purchaseCost' => 'Purchase Cost', + 'purchaseDate' => 'Purchase Date', + 'quantity' => 'Quantity', + 'supplierName' => 'Supplier', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'category' => Str::random(), + 'companyName' => Str::random(), + 'itemName' => Str::random(), + 'location' => "{$faker->city}, {$faker->country}", + 'manufacturerName' => $faker->company, + 'modelNumber' => Str::random(), + 'notes' => $faker->sentence, + 'orderNumber' => Str::random(), + 'purchaseDate' => $faker->date(), + 'purchaseCost' => rand(1, 100), + 'quantity' => rand(1, 100), + 'supplierName' => $faker->company, + ]; + } +} diff --git a/tests/Support/Importing/AssetsImportFileBuilder.php b/tests/Support/Importing/AssetsImportFileBuilder.php new file mode 100644 index 0000000000..df573536c5 --- /dev/null +++ b/tests/Support/Importing/AssetsImportFileBuilder.php @@ -0,0 +1,92 @@ + + */ +class AssetsImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'assigneeFullName' => 'Full Name', + 'assigneeEmail' => 'Email', + 'assigneeUsername' => 'Username', + 'category' => 'Category', + 'companyName' => 'Company', + 'itemName' => 'item Name', + 'location' => 'Location', + 'manufacturerName' => 'Manufacturer', + 'model' => 'Model name', + 'modelNumber' => 'Model Number', + 'notes' => 'Notes', + 'purchaseCost' => 'Purchase Cost', + 'purchaseDate' => 'Purchase Date', + 'serialNumber' => 'Serial number', + 'supplierName' => 'Supplier', + 'status' => 'Status', + 'tag' => 'Asset Tag', + 'warrantyInMonths' => 'Warranty', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'assigneeFullName' => $faker->name, + 'assigneeEmail' => $faker->email, + 'assigneeUsername' => $faker->userName, + 'category' => Str::random(), + 'companyName' => Str::random() . " {$faker->companySuffix}", + 'itemName' => Str::random(), + 'location' => "{$faker->country},{$faker->city}", + 'manufacturerName' => $faker->company, + 'model' => Str::random(), + 'modelNumber' => Str::random(), + 'notes' => $faker->sentence(5), + 'purchaseCost' => rand(1, 100_000), + 'purchaseDate' => $faker->date, + 'serialNumber' => $faker->uuid, + 'supplierName' => $faker->company, + 'status' => $faker->randomElement(['Ready to Deploy', 'Archived', 'Pending']), + 'tag' => Str::random(), + 'warrantyInMonths' => rand(1, 12), + ]; + } +} diff --git a/tests/Support/Importing/ComponentsImportFileBuilder.php b/tests/Support/Importing/ComponentsImportFileBuilder.php new file mode 100644 index 0000000000..6d0b163419 --- /dev/null +++ b/tests/Support/Importing/ComponentsImportFileBuilder.php @@ -0,0 +1,65 @@ + + */ +class ComponentsImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'category' => 'Category', + 'companyName' => 'Company', + 'itemName' => 'item Name', + 'location' => 'Location', + 'orderNumber' => 'Order Number', + 'purchaseCost' => 'Purchase Cost', + 'purchaseDate' => 'Purchase Date', + 'quantity' => 'Quantity', + 'serialNumber' => 'Serial number', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'category' => Str::random(), + 'companyName' => Str::random() . " {$faker->companySuffix}", + 'itemName' => Str::random(), + 'location' => "{$faker->city}, {$faker->country}", + 'orderNumber' => "ON:COM:{$faker->uuid}", + 'purchaseCost' => rand(1, 100_000), + 'purchaseDate' => $faker->date, + 'quantity' => rand(1, 100_000), + 'serialNumber' => 'SN:COM:' . Str::random(), + ]; + } +} diff --git a/tests/Support/Importing/ConsumablesImportFileBuilder.php b/tests/Support/Importing/ConsumablesImportFileBuilder.php new file mode 100644 index 0000000000..16722a2f05 --- /dev/null +++ b/tests/Support/Importing/ConsumablesImportFileBuilder.php @@ -0,0 +1,65 @@ + + */ +class ConsumablesImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'category' => 'Category', + 'companyName' => 'Company', + 'itemName' => 'item Name', + 'location' => 'Location', + 'orderNumber' => 'Order Number', + 'purchaseCost' => 'Purchase Cost', + 'purchaseDate' => 'Purchase Date', + 'quantity' => 'Quantity', + 'supplier' => 'Supplier', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'category' => Str::random(), + 'companyName' => Str::random() . " {$faker->companySuffix}", + 'itemName' => Str::random(), + 'location' => "{$faker->city}, {$faker->country}", + 'orderNumber' => "ON:CON:{$faker->uuid}", + 'purchaseCost' => rand(1, 100_000), + 'purchaseDate' => $faker->date, + 'quantity' => rand(1, 100_000), + 'supplier' => Str::random() . " {$faker->companySuffix}", + ]; + } +} diff --git a/tests/Support/Importing/FileBuilder.php b/tests/Support/Importing/FileBuilder.php new file mode 100644 index 0000000000..fad40054b4 --- /dev/null +++ b/tests/Support/Importing/FileBuilder.php @@ -0,0 +1,249 @@ + + */ + protected Collection $rows; + + /** + * Define the builders default row. + * + * @return Row + */ + abstract public function definition(); + + /** + * @param array $rows + */ + public function __construct(array $rows = []) + { + $this->rows = new Collection($rows); + } + + /** + * Get a new file builder instance. + * + * @param Row $attributes + * + * @return static + */ + public static function new(array $attributes = []) + { + $instance = new static; + + return $instance->push($instance->definition())->replace($attributes); + } + + /** + * Get a new file builder instance from an import file. + * + * @return static + */ + public static function fromFile(string $filepath) + { + $instance = new static; + + $reader = Reader::createFromPath($filepath); + $importFileHeaders = $reader->first(); + $dictionary = array_flip($instance->getDictionary()); + + foreach ($reader->getRecords() as $key => $record) { + $row = []; + + //Skip header. + if ($key === 0) { + continue; + } + + foreach ($record as $index => $value) { + $columnNameInImportFile = $importFileHeaders[$index]; + + //Try to map the value to a dictionary or use the file's + //column if the key is not defined in the dictionary. + $row[$dictionary[$columnNameInImportFile] ?? $columnNameInImportFile] = $value; + } + + $instance->push($row); + } + + return $instance; + } + + /** + * Get a new builder instance for the given number of rows. + * + * @return static + */ + public static function times(int $amountOfRows = 1) + { + $instance = new static; + + for ($i = 1; $i <= $amountOfRows; $i++) { + $instance->push($instance->definition()); + } + + return $instance; + } + + /** + * The the dictionary for mapping row keys to the corresponding import file headers. + * + * @return array + */ + protected function getDictionary(): array + { + return []; + } + + /** + * Add a new row. + * + * @param Row $row + * + * @return $this + */ + public function push(array $row) + { + if (!empty($row)) { + $this->rows->push($row); + } + + return $this; + } + + /** + * Pluck an array of values from the rows. + */ + public function pluck(string $key): array + { + return $this->rows->pluck($key)->all(); + } + + /** + * Replace the keys in each row with the values of the given replacement if they exist. + * + * @param array $replacement + * + * @return $this + */ + public function replace(array $replacement) + { + $this->rows = $this->rows->map(function (array $row) use ($replacement) { + foreach ($replacement as $key => $value) { + if (!array_key_exists($key, $row)) { + continue; + } + + $row[$key] = $value; + } + + return $row; + }); + + return $this; + } + + /** + * Remove the the given keys from all rows. + * + * @param string|array $keys + * + * @return $this + */ + public function forget(array|string $keys) + { + $keys = (array) $keys; + + $this->rows = $this->rows->map(function (array $row) use ($keys) { + foreach ($keys as $key) { + unset($row[$key]); + } + + return $row; + }); + + return $this; + } + + public function toCsv(): array + { + if ($this->rows->isEmpty()) { + return []; + } + + $headers = []; + $rows = $this->rows; + $dictionary = $this->getDictionary(); + + foreach (array_keys($rows->first()) as $key) { + $headers[] = $dictionary[$key] ?? $key; + } + + return $rows + ->map(fn (array $row) => array_values(array_combine($headers, $row))) + ->prepend($headers) + ->all(); + } + + /** + * Save the rows to the imports folder as a csv file. + * + * @return string The filename. + */ + public function saveToImportsDirectory(?string $filename = null): string + { + $filename ??= Str::random(40) . '.csv'; + + try { + $stream = fopen(config('app.private_uploads') . "/imports/{$filename}", 'w'); + + foreach ($this->toCsv() as $row) { + fputcsv($stream, $row); + } + + return $filename; + } finally { + if (is_resource($stream)) { + fclose($stream); + } + } + } + + /** + * Get the first row of the import file. + * + * @throws OutOfBoundsException + * + * @return Row + */ + public function firstRow(): array + { + return $this->rows->first(null, fn () => throw new OutOfBoundsException('Could not retrieve row from collection.')); + } + + /** + * Get the all the rows of the import file. + * + * @return array + */ + public function all(): array + { + return $this->rows->all(); + } +} diff --git a/tests/Support/Importing/LicensesImportFileBuilder.php b/tests/Support/Importing/LicensesImportFileBuilder.php new file mode 100644 index 0000000000..2b5e5c01ee --- /dev/null +++ b/tests/Support/Importing/LicensesImportFileBuilder.php @@ -0,0 +1,86 @@ + + */ +class LicensesImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'category' => 'Category', + 'companyName' => 'Company', + 'expirationDate' => 'expiration date', + 'isMaintained' => 'maintained', + 'isReassignAble' => 'reassignable', + 'licensedToName' => 'Licensed To Name', + 'licensedToEmail' => 'Licensed to Email', + 'licenseName' => 'Item name', + 'manufacturerName' => 'manufacturer', + 'notes' => 'notes', + 'orderNumber' => 'Order Number', + 'purchaseCost' => 'Purchase Cost', + 'purchaseDate' => 'Purchase Date', + 'seats' => 'seats', + 'serialNumber' => 'Serial number', + 'supplierName' => 'supplier', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'category' => Str::random(), + 'companyName' => Str::random() . " {$faker->companySuffix}", + 'expirationDate' => $faker->date, + 'isMaintained' => $faker->randomElement(['TRUE', 'FALSE']), + 'isReassignAble' => $faker->randomElement(['TRUE', 'FALSE']), + 'licensedToName' => $faker->name, + 'licensedToEmail' => $faker->email, + 'licenseName' => $faker->company, + 'manufacturerName' => $faker->company, + 'notes' => $faker->sentence, + 'orderNumber' => "ON:LIC:{$faker->uuid}", + 'purchaseCost' => rand(1, 100_000), + 'purchaseDate' => $faker->date, + 'seats' => rand(1, 10), + 'serialNumber' => 'SN:LIC:' . Str::random(), + 'supplierName' => $faker->company, + ]; + } +} diff --git a/tests/Support/Importing/UsersImportFileBuilder.php b/tests/Support/Importing/UsersImportFileBuilder.php new file mode 100644 index 0000000000..0a00c995c2 --- /dev/null +++ b/tests/Support/Importing/UsersImportFileBuilder.php @@ -0,0 +1,65 @@ + + */ +class UsersImportFileBuilder extends FileBuilder +{ + /** + * @inheritdoc + */ + protected function getDictionary(): array + { + return [ + 'companyName' => 'Company', + 'email' => 'email', + 'employeeNumber' => 'Employee Number', + 'firstName' => 'First Name', + 'lastName' => 'Last Name', + 'location' => 'Location', + 'phoneNumber' => 'Phone Number', + 'position' => 'Job Title', + 'username' => 'Username', + ]; + } + + /** + * @inheritdoc + */ + public function definition(): array + { + $faker = fake(); + + return [ + 'companyName' => $faker->company, + 'email' => Str::random(32) . "@{$faker->freeEmailDomain}", + 'employeeNumber' => $faker->uuid, + 'firstName' => $faker->firstName, + 'lastName' => $faker->lastName, + 'location' => "{$faker->city}, {$faker->country}", + 'phoneNumber' => $faker->phoneNumber, + 'position' => $faker->jobTitle, + 'username' => Str::random(), + ]; + } +} From 5b90d79494215f27f8d1f8b02e1d14c787f44a6a Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Tue, 1 Oct 2024 11:50:48 -0700 Subject: [PATCH 23/86] Use created_by --- tests/Feature/Checkins/Api/AccessoryCheckinTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index d44a05b310..8e7a07fca5 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -71,7 +71,7 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie ->assertStatusMessageIs('success'); $this->assertDatabaseHas('action_logs', [ - 'user_id' => $actor->id, + 'created_by' => $actor->id, 'action_type' => 'checkin from', 'target_id' => $user->id, 'target_type' => User::class, From 3dc64cc5e0465e60116e2afd9e04a865d8781199 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Tue, 1 Oct 2024 13:35:39 -0700 Subject: [PATCH 24/86] Reference accessory checkout and not the accessory --- .../Feature/Checkins/Api/AccessoryCheckinTest.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php index 8e7a07fca5..d5f45f22ae 100644 --- a/tests/Feature/Checkins/Api/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Api/AccessoryCheckinTest.php @@ -14,9 +14,10 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie public function testRequiresPermission() { $accessory = Accessory::factory()->checkedOutToUser()->create(); + $accessoryCheckout = $accessory->checkouts->first(); $this->actingAsForApi(User::factory()->create()) - ->postJson(route('api.accessories.checkin', $accessory)) + ->postJson(route('api.accessories.checkin', $accessoryCheckout)) ->assertForbidden(); } @@ -35,11 +36,11 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie $this->settings->enableMultipleFullCompanySupport(); $this->actingAsForApi($userInCompanyA) - ->postJson(route('api.accessories.checkin', $accessoryForCompanyB)) + ->postJson(route('api.accessories.checkin', $accessoryForCompanyB->checkouts->first())) ->assertForbidden(); $this->actingAsForApi($superUser) - ->postJson(route('api.accessories.checkin', $anotherAccessoryForCompanyB)) + ->postJson(route('api.accessories.checkin', $anotherAccessoryForCompanyB->checkouts->first())) ->assertStatusMessageIs('success'); $this->assertEquals(1, $accessoryForCompanyB->fresh()->checkouts->count(), 'Accessory should not be checked in'); @@ -52,8 +53,10 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie $this->assertEquals(1, $accessory->checkouts->count()); + $accessoryCheckout = $accessory->checkouts->first(); + $this->actingAsForApi(User::factory()->checkinAccessories()->create()) - ->postJson(route('api.accessories.checkin', $accessory)) + ->postJson(route('api.accessories.checkin', $accessoryCheckout)) ->assertStatusMessageIs('success'); $this->assertEquals(0, $accessory->fresh()->checkouts->count(), 'Accessory should be checked in'); @@ -65,9 +68,10 @@ class AccessoryCheckinTest extends TestCase implements TestsFullMultipleCompanie $actor = User::factory()->checkinAccessories()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); + $accessoryCheckout = $accessory->checkouts->first(); $this->actingAsForApi($actor) - ->postJson(route('api.accessories.checkin', $accessory)) + ->postJson(route('api.accessories.checkin', $accessoryCheckout)) ->assertStatusMessageIs('success'); $this->assertDatabaseHas('action_logs', [ From 4d9e85026aa814bd5cba426c339f931cacdafd67 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 2 Oct 2024 15:36:01 +0100 Subject: [PATCH 25/86] Fixed #15439 - check database on healthcheck Signed-off-by: snipe --- app/Http/Controllers/HealthController.php | 29 ++++++++++++++++++++--- app/Http/Kernel.php | 5 ++++ app/Http/Middleware/CheckForSetup.php | 13 ++++++---- routes/web.php | 9 ++++--- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/HealthController.php b/app/Http/Controllers/HealthController.php index c75b903b0b..2a2904e0fb 100644 --- a/app/Http/Controllers/HealthController.php +++ b/app/Http/Controllers/HealthController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use Illuminate\Routing\Controller as BaseController; +use Illuminate\Support\Facades\DB; /** * This controller provide the health route for @@ -15,13 +16,35 @@ use Illuminate\Routing\Controller as BaseController; */ class HealthController extends BaseController { + + public function __construct() + { + $this->middleware('health'); + } + + /** * Returns a fixed JSON content ({ "status": "ok"}) which indicate the app is up and running */ public function get() { - return response()->json([ - 'status' => 'ok', - ]); + try { + + if (DB::select('select 2 + 2')) { + return response()->json([ + 'status' => 'ok', + ]); + } + + } catch (\Exception $e) { + \Log::error('Could not connect to database'); + return response()->json([ + 'status' => 'Could not connect to database', + ], 500); + + } + + die(); + } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 8c9289a799..b69e22e4f9 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -53,6 +53,10 @@ class Kernel extends HttpKernel \App\Http\Middleware\CheckLocale::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], + + 'health' => [ + + ], ]; /** @@ -69,5 +73,6 @@ class Kernel extends HttpKernel 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'health' => null, ]; } diff --git a/app/Http/Middleware/CheckForSetup.php b/app/Http/Middleware/CheckForSetup.php index 4e399ffcff..6cb593b5ff 100644 --- a/app/Http/Middleware/CheckForSetup.php +++ b/app/Http/Middleware/CheckForSetup.php @@ -7,14 +7,19 @@ use Closure; class CheckForSetup { + + protected $except = [ + '_debugbar*', + 'health' + ]; + public function handle($request, Closure $next, $guard = null) { /** - * This is dumb - * @todo Check on removing this, not sure if it's still needed + * Skip this middleware for the debugbar and health check */ - if ($request->is('_debugbar*')) { + if ($request->is($this->except)) { return $next($request); } @@ -25,7 +30,7 @@ class CheckForSetup return $next($request); } } else { - if (! ($request->is('setup*')) && ! ($request->is('.env')) && ! ($request->is('health'))) { + if (! ($request->is('setup*')) && ! ($request->is('.env'))) { return redirect(config('app.url').'/setup'); } diff --git a/routes/web.php b/routes/web.php index f3ba8350f2..60b74476c7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -536,13 +536,16 @@ Route::group(['middleware' => 'web'], function () { )->name('logout.post'); }); -//Auth::routes(); -Route::get( - '/health', +/** + * Health check route - skip middleware + */ +Route::withoutMiddleware(['web'])->get( + '/health', [HealthController::class, 'get'] )->name('health'); + Route::middleware(['auth'])->get( '/', [DashboardController::class, 'index'] From f92bf5dc2067cae2b533090f0c3a947d16fb4d50 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 2 Oct 2024 15:39:27 +0100 Subject: [PATCH 26/86] Updated language for failure Signed-off-by: snipe --- app/Http/Controllers/HealthController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/HealthController.php b/app/Http/Controllers/HealthController.php index 2a2904e0fb..6b59d8a1d0 100644 --- a/app/Http/Controllers/HealthController.php +++ b/app/Http/Controllers/HealthController.php @@ -39,7 +39,7 @@ class HealthController extends BaseController } catch (\Exception $e) { \Log::error('Could not connect to database'); return response()->json([ - 'status' => 'Could not connect to database', + 'status' => 'database connection failed', ], 500); } From b34a7c8aad07ce285e09cfcd4fb779c8c4295d3f Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 2 Oct 2024 15:48:35 +0100 Subject: [PATCH 27/86] Removed die() Signed-off-by: snipe --- app/Http/Controllers/HealthController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/HealthController.php b/app/Http/Controllers/HealthController.php index 6b59d8a1d0..dac1f17bf4 100644 --- a/app/Http/Controllers/HealthController.php +++ b/app/Http/Controllers/HealthController.php @@ -44,7 +44,7 @@ class HealthController extends BaseController } - die(); + } } From ee046a86885deecf15601acd65ee97fac1f6b54e Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 2 Oct 2024 10:50:40 -0700 Subject: [PATCH 28/86] Add matching Model::reguard() --- app/Importer/Importer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index 678fb9ecb2..47de5add4c 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -164,6 +164,7 @@ abstract class Importer $this->log('------------- Action Summary ----------------'); } + Model::reguard(); }); } From 350b627ce1a247b248845b8b85d2a802c8fb8f74 Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Thu, 3 Oct 2024 14:23:40 +0100 Subject: [PATCH 29/86] Fix numeric sort 'ambiguous order clause' error --- app/Http/Controllers/Api/AssetsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index d1d3878705..d4a103be37 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -395,7 +395,7 @@ class AssetsController extends Controller // This may not work for all databases, but it works for MySQL if ($numeric_sort) { - $assets->orderByRaw($sort_override . ' * 1 ' . $order); + $assets->orderByRaw(DB::getTablePrefix() . 'assets.' . $sort_override . ' * 1 ' . $order); } else { $assets->orderBy($sort_override, $order); } From 3c0f4181ae994e6e33c4c15adbb6704be921c99f Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 3 Oct 2024 16:19:06 +0100 Subject: [PATCH 30/86] Use the newer button style Signed-off-by: snipe --- resources/views/account/view-assets.blade.php | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/resources/views/account/view-assets.blade.php b/resources/views/account/view-assets.blade.php index 96b95484a6..e4cb6d33f2 100755 --- a/resources/views/account/view-assets.blade.php +++ b/resources/views/account/view-assets.blade.php @@ -103,20 +103,23 @@ @can('self.profile') @endcan @can('self.api') @@ -124,7 +127,8 @@ @@ -134,10 +138,15 @@ @if (!empty($user->email))
{{ csrf_field() }} - +
@else - + @endif From 7461c3e0ca2af18ed989a5905c84c5710213f1fb Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 3 Oct 2024 16:19:27 +0100 Subject: [PATCH 31/86] Change controller to assume a collection. (This is dumb, but whatever) Signed-off-by: snipe --- app/Http/Controllers/ProfileController.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index abe09e8afa..896c253463 100755 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -194,14 +194,14 @@ class ProfileController extends Controller */ public function printInventory() : View { - $show_user = auth()->user(); + $show_users = User::where('id',auth()->user()->id)->get(); return view('users/print') - ->with('assets', auth()->user()->assets) - ->with('licenses', $show_user->licenses()->get()) - ->with('accessories', $show_user->accessories()->get()) - ->with('consumables', $show_user->consumables()->get()) - ->with('show_user', $show_user) + ->with('assets', auth()->user()->assets()) + ->with('licenses', auth()->user()->licenses()->get()) + ->with('accessories', auth()->user()->accessories()->get()) + ->with('consumables', auth()->user()->consumables()->get()) + ->with('users', $show_users) ->with('settings', Setting::getSettings()); } @@ -222,7 +222,12 @@ class ProfileController extends Controller return redirect()->back()->with('error', trans('admin/users/message.user_has_no_email')); } - $user->notify((new CurrentInventory($user))); + try { + $user->notify((new CurrentInventory($user))); + } catch (\Exception $e) { + \Log::error($e); + } + return redirect()->back()->with('success', trans('admin/users/general.user_notified')); } } From 722d5a58e719886282f908a11420fa88f9fed4fc Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 3 Oct 2024 16:19:38 +0100 Subject: [PATCH 32/86] Added isset on users Signed-off-by: snipe --- resources/views/users/print.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/users/print.blade.php b/resources/views/users/print.blade.php index 7fe92303b3..2211b987bf 100644 --- a/resources/views/users/print.blade.php +++ b/resources/views/users/print.blade.php @@ -2,7 +2,7 @@ - @if (count($users) === 1) + @if ((isset($users) && count($users) === 1)) {{ trans('general.assigned_to', ['name' => $users[0]->present()->fullName()]) }} - {{ date('Y-m-d H:i', time()) }} @else {{ trans('admin/users/general.print_assigned') }} - {{ date('Y-m-d H:i', time()) }} From f483cd448fdcf3dc75482a0e9029f0569fc3916d Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 3 Oct 2024 17:27:37 +0100 Subject: [PATCH 33/86] Smarter work-wrapping on long text Signed-off-by: snipe --- public/css/build/app.css | Bin 28197 -> 28319 bytes public/css/build/overrides.css | Bin 21325 -> 21447 bytes public/css/dist/all.css | Bin 515306 -> 515550 bytes public/mix-manifest.json | 6 +++--- resources/assets/less/overrides.less | 18 ++++++++++-------- resources/views/accessories/view.blade.php | 2 +- resources/views/users/view.blade.php | 2 -- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/public/css/build/app.css b/public/css/build/app.css index 3cea5e2d0f716e93dd96a6c3f99a7e80aba51aea..64021f65d189bb8695d7976f0f448b5fab874803 100644 GIT binary patch delta 236 zcmZ2_hjIR0#tm;>#T69F^NUh+%Zm~VtQ3-pQWLXvK?0LsyVl~AOLH^eDo9L8$;?Z) zQZSl)(oJ0lt0C503JN8ONja&yIf<3|r6pDhX_*zNDU+Gq?+fH)=B4Upq-LgP0EG?p t%qGWsXix5S7oIHR5v`=4fG!O(3SnhI#pGii!F)(UW>|$bi+l2^0syjhQZ)bo delta 74 zcmV-Q0JZ<0-2tWC0kG{wlWj#HlO{%6laomkldVP@lL|#Slh{TfleJY3lWa=}lPO2r glWay0lP5@qlPpLRlSN5BlaomnlSoNBvy({-C3RgKh5!Hn diff --git a/public/css/build/overrides.css b/public/css/build/overrides.css index 52c81f55f6a084d62bf5e97046f3ced868039433..652cd2b0c9aae33704665e80534788f1bbba2265 100644 GIT binary patch delta 252 zcmX@RjPdw##tov{;tC4o`9&$ZSm;7 zre^?!4fV{dC+iuAPoA$UJb9~*@MIU=Xe9*&3^hRW5cU>SOt#mPn9QbU&4(mxhEsU6 Iy&j(`07N@dLjV8( delta 73 zcmX@Uobl{3#tov{ll8Q#Cm+(*n{1?IIk{C!V6uRY;N(^V@yUTYwF7M2#)7Pc+yQ)MR`r%F!Ww1vGI%s8mPEApZ=|hk&ju=%zFAd zC3f-Y@*qRF7M2#)7Pc+yQ)Q>GlVz`-?j*;qH{Ej!yXAE8ZS0DZ<=3%K z=TT-Cn0`@?{r2<*S$6*E0SfG_)3dj;H-ZS^>2DR-?WSMa!7euag95wtb|8yKb-TM8 K`_nus8VCS3f .row:nth-of-type(even) { background: #FFFFFF; border-top: 1px solid #dddddd; + line-height: 1.6; display: table-row; - } .row-new-striped > .row:nth-of-type(odd) { background-color: #F8F8F8; border-top: 1px solid #dddddd; display: table-row; - + line-height: 1.6; + padding: 2px; } .row-new-striped div { display: table-cell; border-top: 1px solid #dddddd; + padding: 6px; } .row-new-striped div { display: table-cell; border-top: 1px solid #dddddd; + padding: 6px; } diff --git a/resources/views/accessories/view.blade.php b/resources/views/accessories/view.blade.php index 41e8d1c41b..1f7e5f0b9a 100644 --- a/resources/views/accessories/view.blade.php +++ b/resources/views/accessories/view.blade.php @@ -301,7 +301,7 @@ {{ trans('general.notes') }} -
+
{!! nl2br(Helper::parseEscapedMarkedownInline($accessory->notes)) !!}
diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index b726d22e90..2c3790b1a8 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -177,8 +177,6 @@
{{ $user->present()->fullName() }}
- - @can('update', $user)
From cb281c6408bb81dd0fbcb8f65e0ad6fea090c154 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 3 Oct 2024 17:33:46 +0100 Subject: [PATCH 34/86] Tweaked line height Signed-off-by: snipe --- public/css/build/app.css | Bin 28319 -> 28319 bytes public/css/build/overrides.css | Bin 21447 -> 21447 bytes public/css/dist/all.css | Bin 515550 -> 515550 bytes public/mix-manifest.json | 6 +++--- resources/assets/less/overrides.less | 6 +++--- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/public/css/build/app.css b/public/css/build/app.css index 64021f65d189bb8695d7976f0f448b5fab874803..d35eebb0a633f49ced37185a5c9d53b93b1997ad 100644 GIT binary patch delta 34 qcmbP#mvR1G#tj$U7>zeya&u&4vb3Ju;4MB`$72$s<>vh!4^#p7LJfcb delta 34 qcmbP#mvR1G#tj$U7>zbxa&u&4GP9oC;4MB`$72$s+2;Ko4^#p60NMY?rvb;O0kHWi0yA)vfGQQU5G*SJ0XdVsEf|wjEs_B_v*#_~B_Ey+KmY&$ delta 38 wcmV+>0NMY?rvb;O0kHWi0y1!ufGQQU5G*SJ0XCDpEf|wjEs_B?v*#_~B_BWzIRF3v diff --git a/public/css/dist/all.css b/public/css/dist/all.css index 81c6964b8dfcd9785783779c2a8cc8acb72a3514..3d3cc4f98f04913563d5e935d0827399bfc0122a 100644 GIT binary patch delta 91 zcmcb&TmIf|`Gyw87N!>F7M2#)7Pc+ym2!;6+Xc6=J2Em^T2J4F7M2#)7Pc+ym2!+m+Xc6=J2EnvSx?`;i(Pzr_ICD3jAqmI SIoL$E*C?=0nMz2-X;lD#CLLD* diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 00b66c0607..291f4f95fe 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -2,8 +2,8 @@ "/js/build/app.js": "/js/build/app.js?id=5e9ac5c1a7e089f056fb1dba566193a6", "/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=f0b08873a06bb54daeee176a9459f4a9", "/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=f4397c717b99fce41a633ca6edd5d1f4", - "/css/build/overrides.css": "/css/build/overrides.css?id=1858a2cb1b0487101fb22f085ac1d6e1", - "/css/build/app.css": "/css/build/app.css?id=6b98e6219316bbfe4cbfeb96546333fe", + "/css/build/overrides.css": "/css/build/overrides.css?id=1c3ffc5fb379e21523f2a9b03f986edb", + "/css/build/app.css": "/css/build/app.css?id=d04f32982fb319ac35a32d362089f18b", "/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=4ea0068716c1bb2434d87a16d51b98c9", "/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=7b315b9612b8fde8f9c5b0ddb6bba690", "/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=393aaa7b368b0670fc42434c8cca7dc7", @@ -19,7 +19,7 @@ "/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=f677207c6cf9678eb539abecb408c374", "/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=0640e45bad692dcf62873c6e85904899", "/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=76482123f6c70e866d6b971ba91de7bb", - "/css/dist/all.css": "/css/dist/all.css?id=564c0a9b1114b4f17b4bed56901e1c39", + "/css/dist/all.css": "/css/dist/all.css?id=9f69886d7a8e4c383cd09a48573922b7", "/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7", "/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde", diff --git a/resources/assets/less/overrides.less b/resources/assets/less/overrides.less index bc10789d9a..8c4f2113a0 100644 --- a/resources/assets/less/overrides.less +++ b/resources/assets/less/overrides.less @@ -640,7 +640,7 @@ h4 { .row-new-striped { vertical-align: top; - padding: 2px; + padding: 3px; display: table; width: 100%; word-wrap: break-word; @@ -655,7 +655,7 @@ h4 { .row-new-striped > .row:nth-of-type(even) { background: #FFFFFF; border-top: 1px solid #dddddd; - line-height: 1.6; + line-height: 1.9; display: table-row; } @@ -663,7 +663,7 @@ h4 { background-color: #F8F8F8; border-top: 1px solid #dddddd; display: table-row; - line-height: 1.6; + line-height: 1.9; padding: 2px; } From 863c0a8b609d9c407bf7ed038bcb7db0e40dd4df Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 11:43:02 -0700 Subject: [PATCH 35/86] Fix import_type for accessory state --- database/factories/ImportFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/factories/ImportFactory.php b/database/factories/ImportFactory.php index 4fafc96216..830c87fa76 100644 --- a/database/factories/ImportFactory.php +++ b/database/factories/ImportFactory.php @@ -41,7 +41,7 @@ class ImportFactory extends Factory $fileBuilder = Importing\AccessoriesImportFileBuilder::new(); $attributes['name'] = "{$attributes['name']} Accessories"; - $attributes['import_type'] = 'Accessories'; + $attributes['import_type'] = 'accessory'; $attributes['header_row'] = $fileBuilder->toCsv()[0]; $attributes['first_row'] = $fileBuilder->firstRow(); From b5ffe54bd07bd6a14216e993142e9086fbdee9e7 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 13:15:02 -0700 Subject: [PATCH 36/86] Swap assertEquals parameter order --- .../Importing/Api/ImportAccessoriesTest.php | 84 ++++---- .../Importing/Api/ImportAssetsTest.php | 188 +++++++++--------- .../Importing/Api/ImportComponentsTest.php | 62 +++--- .../Importing/Api/ImportConsumablesTest.php | 54 ++--- .../Importing/Api/ImportLicenseTest.php | 106 +++++----- .../Feature/Importing/Api/ImportUsersTest.php | 120 +++++------ 6 files changed, 307 insertions(+), 307 deletions(-) diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php index cf7597c314..27a80c0dd0 100644 --- a/tests/Feature/Importing/Api/ImportAccessoriesTest.php +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -81,23 +81,23 @@ class ImportAccessoriesTest extends ImportDataTestCase ->where('item_id', $newAccessory->id) ->sole(); - $this->assertEquals($activityLog->action_type, 'create'); - $this->assertEquals($activityLog->action_source, 'importer'); - $this->assertEquals($activityLog->company_id, $newAccessory->company->id); + $this->assertEquals('create', $activityLog->action_type); + $this->assertEquals('importer', $activityLog->action_source); + $this->assertEquals($newAccessory->company->id, $activityLog->company_id); - $this->assertEquals($newAccessory->name, $row['itemName']); - $this->assertEquals($newAccessory->qty, $row['quantity']); - $this->assertEquals($newAccessory->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($newAccessory->purchase_cost, $row['purchaseCost']); - $this->assertEquals($newAccessory->order_number, $row['orderNumber']); - $this->assertEquals($newAccessory->notes, $row['notes']); - $this->assertEquals($newAccessory->category->name, $row['category']); - $this->assertEquals($newAccessory->category->category_type, 'accessory'); - $this->assertEquals($newAccessory->manufacturer->name, $row['manufacturerName']); - $this->assertEquals($newAccessory->supplier->name, $row['supplierName']); - $this->assertEquals($newAccessory->location->name, $row['location']); - $this->assertEquals($newAccessory->company->name, $row['companyName']); - $this->assertEquals($newAccessory->model_number, $row['modelNumber']); + $this->assertEquals($row['itemName'], $newAccessory->name); + $this->assertEquals($row['quantity'], $newAccessory->qty); + $this->assertEquals($row['purchaseDate'], $newAccessory->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $newAccessory->purchase_cost); + $this->assertEquals($row['orderNumber'], $newAccessory->order_number); + $this->assertEquals($row['notes'], $newAccessory->notes); + $this->assertEquals($row['category'], $newAccessory->category->name); + $this->assertEquals('accessory', $newAccessory->category->category_type); + $this->assertEquals($row['manufacturerName'], $newAccessory->manufacturer->name); + $this->assertEquals($row['supplierName'], $newAccessory->supplier->name); + $this->assertEquals($row['location'], $newAccessory->location->name); + $this->assertEquals($row['companyName'], $newAccessory->company->name); + $this->assertEquals($row['modelNumber'], $newAccessory->model_number); $this->assertFalse($newAccessory->requestable); $this->assertNull($newAccessory->min_amt); $this->assertNull($newAccessory->user_id); @@ -131,7 +131,7 @@ class ImportAccessoriesTest extends ImportDataTestCase ->where('name', $importFileBuilder->firstRow()['itemName']) ->sole(['purchase_date']); - $this->assertEquals($accessory->purchase_date->toDateString(), '2022-10-10'); + $this->assertEquals('2022-10-10', $accessory->purchase_date->toDateString()); } #[Test] @@ -165,7 +165,7 @@ class ImportAccessoriesTest extends ImportDataTestCase ->get(['name']); $this->assertCount(1, $probablyNewAccessories); - $this->assertEquals($probablyNewAccessories->first()->name, $accessory->name); + $this->assertEquals($accessory->name, $probablyNewAccessories->first()->name); } #[Test] @@ -292,23 +292,23 @@ class ImportAccessoriesTest extends ImportDataTestCase 'location_id', 'model_number', 'updated_at' ]; - $this->assertEquals($updatedAccessory->name, $row['itemName']); + $this->assertEquals($row['itemName'], $updatedAccessory->name); $this->assertEquals($row['companyName'], $updatedAccessory->company->name); - $this->assertEquals($updatedAccessory->qty, $row['quantity']); - $this->assertEquals($updatedAccessory->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($updatedAccessory->purchase_cost, $row['purchaseCost']); - $this->assertEquals($updatedAccessory->order_number, $row['orderNumber']); - $this->assertEquals($updatedAccessory->notes, $row['notes']); - $this->assertEquals($updatedAccessory->category->name, $row['category']); - $this->assertEquals($updatedAccessory->category->category_type, 'accessory'); - $this->assertEquals($updatedAccessory->manufacturer->name, $row['manufacturerName']); - $this->assertEquals($updatedAccessory->supplier->name, $row['supplierName']); - $this->assertEquals($updatedAccessory->location->name, $row['location']); - $this->assertEquals($updatedAccessory->model_number, $row['modelNumber']); + $this->assertEquals($row['quantity'], $updatedAccessory->qty); + $this->assertEquals($row['purchaseDate'], $updatedAccessory->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $updatedAccessory->purchase_cost); + $this->assertEquals($row['orderNumber'], $updatedAccessory->order_number); + $this->assertEquals($row['notes'], $updatedAccessory->notes); + $this->assertEquals($row['category'], $updatedAccessory->category->name); + $this->assertEquals('accessory', $updatedAccessory->category->category_type); + $this->assertEquals($row['manufacturerName'], $updatedAccessory->manufacturer->name); + $this->assertEquals($row['supplierName'], $updatedAccessory->supplier->name); + $this->assertEquals($row['location'], $updatedAccessory->location->name); + $this->assertEquals($row['modelNumber'], $updatedAccessory->model_number); $this->assertEquals( - Arr::except($updatedAccessory->attributesToArray(), $updatedAttributes), Arr::except($accessory->attributesToArray(), $updatedAttributes), + Arr::except($updatedAccessory->attributesToArray(), $updatedAttributes), ); } @@ -362,7 +362,7 @@ class ImportAccessoriesTest extends ImportDataTestCase $updatedAccessory = clone $accessory; $updatedAccessory->refresh(); - $this->assertEquals($updatedAccessory->toArray(), $accessory->toArray()); + $this->assertEquals($accessory->toArray(), $updatedAccessory->toArray()); } #[Test] @@ -412,15 +412,15 @@ class ImportAccessoriesTest extends ImportDataTestCase ->where('name', $row['modelNumber']) ->sole(); - $this->assertEquals($newAccessory->name, $row['modelNumber']); - $this->assertEquals($newAccessory->model_number, $row['itemName']); - $this->assertEquals($newAccessory->qty, $row['quantity']); - $this->assertEquals($newAccessory->purchase_date->toDateString(), $row['notes']); - $this->assertEquals($newAccessory->purchase_cost, $row['location']); - $this->assertEquals($newAccessory->order_number, $row['companyName']); - $this->assertEquals($newAccessory->notes, $row['purchaseDate']); - $this->assertEquals($newAccessory->category->name, $row['manufacturerName']); - $this->assertEquals($newAccessory->manufacturer->name, $row['category']); - $this->assertEquals($newAccessory->location->name, $row['purchaseCost']); + $this->assertEquals($row['modelNumber'], $newAccessory->name); + $this->assertEquals($row['itemName'], $newAccessory->model_number); + $this->assertEquals($row['quantity'], $newAccessory->qty); + $this->assertEquals($row['notes'], $newAccessory->purchase_date->toDateString()); + $this->assertEquals($row['location'], $newAccessory->purchase_cost); + $this->assertEquals($row['companyName'], $newAccessory->order_number); + $this->assertEquals($row['purchaseDate'], $newAccessory->notes); + $this->assertEquals($row['manufacturerName'], $newAccessory->category->name); + $this->assertEquals($row['category'], $newAccessory->manufacturer->name); + $this->assertEquals($row['purchaseCost'], $newAccessory->location->name); } } diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index b7c6298d32..d4b6ac52e7 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -89,60 +89,60 @@ class ImportAssetsTest extends ImportDataTestCase $this->assertCount(2, $activityLogs); - $this->assertEquals($activityLogs[0]->action_type, 'checkout'); - $this->assertEquals($activityLogs[0]->item_type, Asset::class); - $this->assertEquals($activityLogs[0]->target_id, $assignee->id); - $this->assertEquals($activityLogs[0]->target_type, User::class); - $this->assertEquals($activityLogs[0]->note, 'Checkout from CSV Importer'); + $this->assertEquals('checkout', $activityLogs[0]->action_type); + $this->assertEquals(Asset::class, $activityLogs[0]->item_type); + $this->assertEquals($assignee->id, $activityLogs[0]->target_id); + $this->assertEquals(User::class, $activityLogs[0]->target_type); + $this->assertEquals('Checkout from CSV Importer', $activityLogs[0]->note); - $this->assertEquals($activityLogs[1]->action_type, 'create'); + $this->assertEquals('create', $activityLogs[1]->action_type); $this->assertNull($activityLogs[1]->target_id); - $this->assertEquals($activityLogs[1]->item_type, Asset::class); + $this->assertEquals(Asset::class, $activityLogs[1]->item_type); $this->assertNull($activityLogs[1]->note); $this->assertNull($activityLogs[1]->target_type); - $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['assigneeFullName']); - $this->assertEquals($assignee->email, $row['assigneeEmail']); - $this->assertEquals($assignee->username, $row['assigneeUsername']); + $this->assertEquals($row['assigneeFullName'], "{$assignee->first_name} {$assignee->last_name}"); + $this->assertEquals($row['assigneeEmail'], $assignee->email); + $this->assertEquals($row['assigneeUsername'], $assignee->username); - $this->assertEquals($newAsset->model->category->name, $row['category']); - $this->assertEquals($newAsset->model->manufacturer->name, $row['manufacturerName']); - $this->assertEquals($newAsset->name, $row['itemName']); - $this->assertEquals($newAsset->asset_tag, $row['tag']); - $this->assertEquals($newAsset->model->name, $row['model']); - $this->assertEquals($newAsset->model->model_number, $row['modelNumber']); - $this->assertEquals($newAsset->purchase_date->toDateString(), $row['purchaseDate']); + $this->assertEquals($row['category'], $newAsset->model->category->name); + $this->assertEquals($row['manufacturerName'], $newAsset->model->manufacturer->name); + $this->assertEquals($row['itemName'], $newAsset->name); + $this->assertEquals($row['tag'], $newAsset->asset_tag); + $this->assertEquals($row['model'], $newAsset->model->name); + $this->assertEquals($row['modelNumber'], $newAsset->model->model_number); + $this->assertEquals($row['purchaseDate'], $newAsset->purchase_date->toDateString()); $this->assertNull($newAsset->asset_eol_date); $this->assertEquals(0, $newAsset->eol_explicit); $this->assertEquals($newAsset->location_id, $newAsset->rtd_location_id); - $this->assertEquals($newAsset->purchase_cost, $row['purchaseCost']); + $this->assertEquals($row['purchaseCost'], $newAsset->purchase_cost); $this->assertNull($newAsset->order_number); - $this->assertEquals($newAsset->image, ''); + $this->assertEquals('', $newAsset->image); $this->assertNull($newAsset->user_id); - $this->assertEquals($newAsset->physical, 1); - $this->assertEquals($newAsset->assetStatus->name, $row['status']); - $this->assertEquals($newAsset->archived, 0); - $this->assertEquals($newAsset->warranty_months, $row['warrantyInMonths']); + $this->assertEquals(1, $newAsset->physical); + $this->assertEquals($row['status'], $newAsset->assetStatus->name); + $this->assertEquals(0, $newAsset->archived); + $this->assertEquals($row['warrantyInMonths'], $newAsset->warranty_months); $this->assertNull($newAsset->deprecate); - $this->assertEquals($newAsset->supplier->name, $row['supplierName']); - $this->assertEquals($newAsset->requestable, 0); - $this->assertEquals($newAsset->defaultLoc->name, $row['location']); - $this->assertEquals($newAsset->accepted, null); - $this->assertEquals(Carbon::parse($newAsset->last_checkout)->toDateString(), now()->toDateString()); - $this->assertEquals($newAsset->last_checkin, 0); - $this->assertEquals($newAsset->expected_checkin, 0); - $this->assertEquals($newAsset->company->name, $row['companyName']); - $this->assertEquals($newAsset->assigned_type, User::class); + $this->assertEquals($row['supplierName'], $newAsset->supplier->name); + $this->assertEquals(0, $newAsset->requestable); + $this->assertEquals($row['location'], $newAsset->defaultLoc->name); + $this->assertEquals(null, $newAsset->accepted); + $this->assertEquals(now()->toDateString(), Carbon::parse($newAsset->last_checkout)->toDateString()); + $this->assertEquals(0, $newAsset->last_checkin); + $this->assertEquals(0, $newAsset->expected_checkin); + $this->assertEquals($row['companyName'], $newAsset->company->name); + $this->assertEquals(User::class, $newAsset->assigned_type); $this->assertNull($newAsset->last_audit_date); $this->assertNull($newAsset->next_audit_date); - $this->assertEquals($newAsset->location->name, $row['location']); - $this->assertEquals($newAsset->checkin_counter, 0); - $this->assertEquals($newAsset->checkout_counter, 1); - $this->assertEquals($newAsset->requests_counter, 0); - $this->assertEquals($newAsset->byod, 0); + $this->assertEquals($row['location'], $newAsset->location->name); + $this->assertEquals(0, $newAsset->checkin_counter); + $this->assertEquals(1, $newAsset->checkout_counter); + $this->assertEquals(0, $newAsset->requests_counter); + $this->assertEquals(0, $newAsset->byod); //Notes is never read. - //$this->assertEquals($asset->notes, $row['notes']); + // $this->assertEquals($row['notes'], $newAsset->notes); Notification::assertSentTo($assignee, CheckoutAssetNotification::class); } @@ -309,7 +309,7 @@ class ImportAssetsTest extends ImportDataTestCase ->where('serial', $importFileBuilder->firstRow()['serialNumber']) ->sole(); - $this->assertEquals($newAsset->assetStatus->name, 'Ready to Deploy'); + $this->assertEquals('Ready to Deploy', $newAsset->assetStatus->name); $this->assertNull($newAsset->purchase_date); $this->assertNull($newAsset->purchase_cost); } @@ -331,8 +331,8 @@ class ImportAssetsTest extends ImportDataTestCase ->where('serial', $importFileBuilder->firstRow()['serialNumber']) ->sole(); - $this->assertEquals($newAsset->warranty_months, 3); - $this->assertEquals($newAsset->purchase_date->toDateString(), '2022-10-10'); + $this->assertEquals(3, $newAsset->warranty_months); + $this->assertEquals('2022-10-10', $newAsset->purchase_date->toDateString()); } #[Test] @@ -406,33 +406,33 @@ class ImportAssetsTest extends ImportDataTestCase 'last_checkout', 'requestable', 'updated_at', 'checkout_counter', 'assigned_type' ]; - $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['assigneeFullName']); - $this->assertEquals($assignee->email, $row['assigneeEmail']); - $this->assertEquals($assignee->username, $row['assigneeUsername']); + $this->assertEquals($row['assigneeFullName'], "{$assignee->first_name} {$assignee->last_name}"); + $this->assertEquals($row['assigneeEmail'], $assignee->email); + $this->assertEquals($row['assigneeUsername'], $assignee->username); - $this->assertEquals($updatedAsset->model->category->name, $row['category']); - $this->assertEquals($updatedAsset->model->manufacturer->name, $row['manufacturerName']); - $this->assertEquals($updatedAsset->name, $row['itemName']); - $this->assertEquals($updatedAsset->asset_tag, $row['tag']); - $this->assertEquals($updatedAsset->model->name, $row['model']); - $this->assertEquals($updatedAsset->model->model_number, $row['modelNumber']); - $this->assertEquals($updatedAsset->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($updatedAsset->purchase_cost, $row['purchaseCost']); - $this->assertEquals($updatedAsset->assetStatus->name, $row['status']); - $this->assertEquals($updatedAsset->warranty_months, $row['warrantyInMonths']); - $this->assertEquals($updatedAsset->supplier->name, $row['supplierName']); - $this->assertEquals($updatedAsset->defaultLoc->name, $row['location']); - $this->assertEquals($updatedAsset->company->name, $row['companyName']); - $this->assertEquals($updatedAsset->location->name, $row['location']); - $this->assertEquals($updatedAsset->checkout_counter, 1); - $this->assertEquals($updatedAsset->assigned_type, user::class); + $this->assertEquals($row['category'], $updatedAsset->model->category->name); + $this->assertEquals($row['manufacturerName'], $updatedAsset->model->manufacturer->name); + $this->assertEquals($row['itemName'], $updatedAsset->name); + $this->assertEquals($row['tag'], $updatedAsset->asset_tag); + $this->assertEquals($row['model'], $updatedAsset->model->name); + $this->assertEquals($row['modelNumber'], $updatedAsset->model->model_number); + $this->assertEquals($row['purchaseDate'], $updatedAsset->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $updatedAsset->purchase_cost); + $this->assertEquals($row['status'], $updatedAsset->assetStatus->name); + $this->assertEquals($row['warrantyInMonths'], $updatedAsset->warranty_months); + $this->assertEquals($row['supplierName'], $updatedAsset->supplier->name); + $this->assertEquals($row['location'], $updatedAsset->defaultLoc->name); + $this->assertEquals($row['companyName'], $updatedAsset->company->name); + $this->assertEquals($row['location'], $updatedAsset->location->name); + $this->assertEquals(1, $updatedAsset->checkout_counter); + $this->assertEquals(user::class, $updatedAsset->assigned_type); //RequestAble is always updated regardless of initial value. - //$this->assertEquals($updatedAsset->requestable, $asset->requestable); + // $this->assertEquals($asset->requestable, $updatedAsset->requestable); $this->assertEquals( - Arr::except($updatedAsset->attributesToArray(), $updatedAttributes), Arr::except($asset->attributesToArray(), $updatedAttributes), + Arr::except($updatedAsset->attributesToArray(), $updatedAttributes), ); } @@ -497,45 +497,45 @@ class ImportAssetsTest extends ImportDataTestCase $assignee = User::query()->find($asset->assigned_to, ['id', 'first_name', 'last_name', 'email', 'username']); - $this->assertEquals("{$assignee->first_name} {$assignee->last_name}", $row['warrantyInMonths']); - $this->assertEquals($assignee->email, $row['tag']); - $this->assertEquals($assignee->username, $row['location']); + $this->assertEquals($row['warrantyInMonths'], "{$assignee->first_name} {$assignee->last_name}"); + $this->assertEquals($row['tag'], $assignee->email); + $this->assertEquals($row['location'], $assignee->username); - $this->assertEquals($asset->model->category->name, $row['modelNumber']); - $this->assertEquals($asset->model->manufacturer->name, $row['assigneeEmail']); - $this->assertEquals($asset->name, $row['model']); - $this->assertEquals($asset->asset_tag, $row['serialNumber']); - $this->assertEquals($asset->model->name, $row['purchaseCost']); - $this->assertEquals($asset->model->model_number, $row['itemName']); - $this->assertEquals($asset->purchase_date->toDateString(), $row['supplierName']); - $this->assertEquals($asset->purchase_cost, $row['companyName']); - $this->assertEquals($asset->assetStatus->name, $row['manufacturerName']); - $this->assertEquals($asset->warranty_months, $row['status']); - $this->assertEquals($asset->supplier->name, $row['assigneeFullName']); - $this->assertEquals($asset->defaultLoc->name, $row['category']); - $this->assertEquals($asset->company->name, $row['purchaseDate']); - $this->assertEquals($asset->location->name, $row['category']); - $this->assertEquals($asset->notes, $row['notes']); + $this->assertEquals($row['modelNumber'], $asset->model->category->name); + $this->assertEquals($row['assigneeEmail'], $asset->model->manufacturer->name); + $this->assertEquals($row['model'], $asset->name); + $this->assertEquals($row['serialNumber'], $asset->asset_tag); + $this->assertEquals($row['purchaseCost'], $asset->model->name); + $this->assertEquals($row['itemName'], $asset->model->model_number); + $this->assertEquals($row['supplierName'], $asset->purchase_date->toDateString()); + $this->assertEquals($row['companyName'], $asset->purchase_cost); + $this->assertEquals($row['manufacturerName'], $asset->assetStatus->name); + $this->assertEquals($row['status'], $asset->warranty_months); + $this->assertEquals($row['assigneeFullName'], $asset->supplier->name); + $this->assertEquals($row['category'], $asset->defaultLoc->name); + $this->assertEquals($row['purchaseDate'], $asset->company->name); + $this->assertEquals($row['category'], $asset->location->name); + $this->assertEquals($row['notes'], $asset->notes); $this->assertNull($asset->asset_eol_date); $this->assertEquals(0, $asset->eol_explicit); $this->assertNull($asset->order_number); - $this->assertEquals($asset->image, ''); + $this->assertEquals('', $asset->image); $this->assertNull($asset->user_id); - $this->assertEquals($asset->physical, 1); - $this->assertEquals($asset->archived, 0); + $this->assertEquals(1, $asset->physical); + $this->assertEquals(0, $asset->archived); $this->assertNull($asset->deprecate); - $this->assertEquals($asset->requestable, 0); - $this->assertEquals($asset->accepted, null); - $this->assertEquals(Carbon::parse($asset->last_checkout)->toDateString(), now()->toDateString()); - $this->assertEquals($asset->last_checkin, 0); - $this->assertEquals($asset->expected_checkin, 0); - $this->assertEquals($asset->assigned_type, User::class); + $this->assertEquals(0, $asset->requestable); + $this->assertEquals(null, $asset->accepted); + $this->assertEquals(now()->toDateString(), Carbon::parse($asset->last_checkout)->toDateString()); + $this->assertEquals(0, $asset->last_checkin); + $this->assertEquals(0, $asset->expected_checkin); + $this->assertEquals(User::class, $asset->assigned_type); $this->assertNull($asset->last_audit_date); $this->assertNull($asset->next_audit_date); - $this->assertEquals($asset->checkin_counter, 0); - $this->assertEquals($asset->checkout_counter, 1); - $this->assertEquals($asset->requests_counter, 0); - $this->assertEquals($asset->byod, 0); + $this->assertEquals(0, $asset->checkin_counter); + $this->assertEquals(1, $asset->checkout_counter); + $this->assertEquals(0, $asset->requests_counter); + $this->assertEquals(0, $asset->byod); } #[Test] @@ -565,7 +565,7 @@ class ImportAssetsTest extends ImportDataTestCase $newAsset = Asset::query()->where('serial', $importFileBuilder->firstRow()['serialNumber'])->sole(); - $this->assertEquals($newAsset->getAttribute($customField->db_column), $macAddress); + $this->assertEquals($macAddress, $newAsset->getAttribute($customField->db_column)); } #[Test] diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php index 56c40ba462..1a68fbf1c2 100644 --- a/tests/Feature/Importing/Api/ImportComponentsTest.php +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -79,21 +79,21 @@ class ImportComponentsTest extends ImportDataTestCase ->where('item_id', $newComponent->id) ->sole(); - $this->assertEquals($activityLog->action_type, 'create'); - $this->assertEquals($activityLog->action_source, 'importer'); - $this->assertEquals($activityLog->company_id, $newComponent->company->id); + $this->assertEquals('create', $activityLog->action_type); + $this->assertEquals('importer', $activityLog->action_source); + $this->assertEquals($newComponent->company->id, $activityLog->company_id); - $this->assertEquals($newComponent->name, $row['itemName']); - $this->assertEquals($newComponent->company->name, $row['companyName']); - $this->assertEquals($newComponent->category->name, $row['category']); - $this->assertEquals($newComponent->location->name, $row['location']); + $this->assertEquals($row['itemName'], $newComponent->name); + $this->assertEquals($row['companyName'], $newComponent->company->name); + $this->assertEquals($row['category'], $newComponent->category->name); + $this->assertEquals($row['location'], $newComponent->location->name); $this->assertNull($newComponent->supplier_id); - $this->assertEquals($newComponent->qty, $row['quantity']); - $this->assertEquals($newComponent->order_number, $row['orderNumber']); - $this->assertEquals($newComponent->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($newComponent->purchase_cost, $row['purchaseCost']); + $this->assertEquals($row['quantity'], $newComponent->qty); + $this->assertEquals($row['orderNumber'], $newComponent->order_number); + $this->assertEquals($row['purchaseDate'], $newComponent->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $newComponent->purchase_cost); $this->assertNull($newComponent->min_amt); - $this->assertEquals($newComponent->serial, $row['serialNumber']); + $this->assertEquals($row['serialNumber'], $newComponent->serial); $this->assertNull($newComponent->image); $this->assertNull($newComponent->notes); } @@ -239,18 +239,18 @@ class ImportComponentsTest extends ImportDataTestCase ->where('serial', $row['serialNumber']) ->sole(); - $this->assertEquals($updatedComponent->name, $row['itemName']); - $this->assertEquals($updatedComponent->category->name, $row['category']); - $this->assertEquals($updatedComponent->location->name, $row['location']); - $this->assertEquals($updatedComponent->supplier_id, $component->supplier_id); - $this->assertEquals($updatedComponent->qty, $row['quantity']); - $this->assertEquals($updatedComponent->order_number, $row['orderNumber']); - $this->assertEquals($updatedComponent->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($updatedComponent->purchase_cost, $row['purchaseCost']); - $this->assertEquals($updatedComponent->min_amt, $component->min_amt); - $this->assertEquals($updatedComponent->serial, $row['serialNumber']); - $this->assertEquals($updatedComponent->image, $component->image); - $this->assertEquals($updatedComponent->notes, $component->notes); + $this->assertEquals($row['itemName'], $updatedComponent->name); + $this->assertEquals($row['category'], $updatedComponent->category->name); + $this->assertEquals($row['location'], $updatedComponent->location->name); + $this->assertEquals($component->supplier_id, $updatedComponent->supplier_id); + $this->assertEquals($row['quantity'], $updatedComponent->qty); + $this->assertEquals($row['orderNumber'], $updatedComponent->order_number); + $this->assertEquals($row['purchaseDate'], $updatedComponent->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $updatedComponent->purchase_cost); + $this->assertEquals($component->min_amt, $updatedComponent->min_amt); + $this->assertEquals($row['serialNumber'], $updatedComponent->serial); + $this->assertEquals($component->image, $updatedComponent->image); + $this->assertEquals($component->notes, $updatedComponent->notes); } #[Test] @@ -294,14 +294,14 @@ class ImportComponentsTest extends ImportDataTestCase ->where('serial', $importFileBuilder->firstRow()['category']) ->sole(); - $this->assertEquals($newComponent->name, $row['quantity']); - $this->assertEquals($newComponent->category->name, $row['purchaseCost']); - $this->assertEquals($newComponent->location->name, $row['serialNumber']); + $this->assertEquals($row['quantity'], $newComponent->name); + $this->assertEquals($row['purchaseCost'], $newComponent->category->name); + $this->assertEquals($row['serialNumber'], $newComponent->location->name); $this->assertNull($newComponent->supplier_id); - $this->assertEquals($newComponent->qty, $row['companyName']); - $this->assertEquals($newComponent->order_number, $row['orderNumber']); - $this->assertEquals($newComponent->purchase_date->toDateString(), $row['itemName']); - $this->assertEquals($newComponent->purchase_cost, $row['location']); + $this->assertEquals($row['companyName'], $newComponent->qty); + $this->assertEquals($row['orderNumber'], $newComponent->order_number); + $this->assertEquals($row['itemName'], $newComponent->purchase_date->toDateString()); + $this->assertEquals($row['location'], $newComponent->purchase_cost); $this->assertNull($newComponent->min_amt); $this->assertNull($newComponent->image); $this->assertNull($newComponent->notes); diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php index 7591ee9711..3962dea5d4 100644 --- a/tests/Feature/Importing/Api/ImportConsumablesTest.php +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -79,22 +79,22 @@ class ImportConsumablesTest extends ImportDataTestCase ->where('item_id', $newConsumable->id) ->sole(); - $this->assertEquals($activityLog->action_type, 'create'); - $this->assertEquals($activityLog->action_source, 'importer'); - $this->assertEquals($activityLog->company_id, $newConsumable->company->id); + $this->assertEquals('create', $activityLog->action_type); + $this->assertEquals('importer', $activityLog->action_source); + $this->assertEquals($newConsumable->company->id, $activityLog->company_id); - $this->assertEquals($newConsumable->name, $row['itemName']); - $this->assertEquals($newConsumable->category->name, $row['category']); - $this->assertEquals($newConsumable->location->name, $row['location']); - $this->assertEquals($newConsumable->company->name, $row['companyName']); + $this->assertEquals($row['itemName'], $newConsumable->name); + $this->assertEquals($row['category'], $newConsumable->category->name); + $this->assertEquals($row['location'], $newConsumable->location->name); + $this->assertEquals($row['companyName'], $newConsumable->company->name); $this->assertNull($newConsumable->supplier_id); $this->assertFalse($newConsumable->requestable); $this->assertNull($newConsumable->image); - $this->assertEquals($newConsumable->order_number, $row['orderNumber']); - $this->assertEquals($newConsumable->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($newConsumable->purchase_cost, $row['purchaseCost']); + $this->assertEquals($row['orderNumber'], $newConsumable->order_number); + $this->assertEquals($row['purchaseDate'], $newConsumable->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $newConsumable->purchase_cost); $this->assertNull($newConsumable->min_amt); - $this->assertEquals($newConsumable->model_number, ''); + $this->assertEquals('', $newConsumable->model_number); $this->assertNull($newConsumable->item_number); $this->assertNull($newConsumable->manufacturer_id); $this->assertNull($newConsumable->notes); @@ -229,13 +229,13 @@ class ImportConsumablesTest extends ImportDataTestCase ->where('name', $importFileBuilder->firstRow()['itemName']) ->sole(); - $this->assertEquals($updatedConsumable->name, $row['itemName']); - $this->assertEquals($updatedConsumable->category->name, $row['category']); - $this->assertEquals($updatedConsumable->location->name, $row['location']); - $this->assertEquals($updatedConsumable->company->name, $row['companyName']); - $this->assertEquals($updatedConsumable->order_number, $row['orderNumber']); - $this->assertEquals($updatedConsumable->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($updatedConsumable->purchase_cost, $row['purchaseCost']); + $this->assertEquals($row['itemName'], $updatedConsumable->name); + $this->assertEquals($row['category'], $updatedConsumable->category->name); + $this->assertEquals($row['location'], $updatedConsumable->location->name); + $this->assertEquals($row['companyName'], $updatedConsumable->company->name); + $this->assertEquals($row['orderNumber'], $updatedConsumable->order_number); + $this->assertEquals($row['purchaseDate'], $updatedConsumable->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $updatedConsumable->purchase_cost); $this->assertEquals($consumable->supplier_id, $updatedConsumable->supplier_id); $this->assertEquals($consumable->requestable, $updatedConsumable->requestable); @@ -289,19 +289,19 @@ class ImportConsumablesTest extends ImportDataTestCase ->where('name', $importFileBuilder->firstRow()['quantity']) ->sole(); - $this->assertEquals($newConsumable->category->name, $row['supplier']); - $this->assertEquals($newConsumable->location->name, $row['purchaseCost']); - $this->assertEquals($newConsumable->company->name, $row['purchaseDate']); - $this->assertEquals($newConsumable->qty, $row['companyName']); - $this->assertEquals($newConsumable->name, $row['quantity']); + $this->assertEquals($row['supplier'], $newConsumable->category->name); + $this->assertEquals($row['purchaseCost'], $newConsumable->location->name); + $this->assertEquals($row['purchaseDate'], $newConsumable->company->name); + $this->assertEquals($row['companyName'], $newConsumable->qty); + $this->assertEquals($row['quantity'], $newConsumable->name); $this->assertNull($newConsumable->supplier_id); $this->assertFalse($newConsumable->requestable); $this->assertNull($newConsumable->image); - $this->assertEquals($newConsumable->order_number, $row['orderNumber']); - $this->assertEquals($newConsumable->purchase_date->toDateString(), $row['itemName']); - $this->assertEquals($newConsumable->purchase_cost, $row['location']); + $this->assertEquals($row['orderNumber'], $newConsumable->order_number); + $this->assertEquals($row['itemName'], $newConsumable->purchase_date->toDateString()); + $this->assertEquals($row['location'], $newConsumable->purchase_cost); $this->assertNull($newConsumable->min_amt); - $this->assertEquals($newConsumable->model_number, ''); + $this->assertEquals('', $newConsumable->model_number); $this->assertNull($newConsumable->item_number); $this->assertNull($newConsumable->manufacturer_id); $this->assertNull($newConsumable->notes); diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php index a5147d55ae..11865236f3 100644 --- a/tests/Feature/Importing/Api/ImportLicenseTest.php +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -79,22 +79,22 @@ class ImportLicenseTest extends ImportDataTestCase $this->assertCount(2, $activityLogs); - $this->assertEquals($newLicense->name, $row['licenseName']); - $this->assertEquals($newLicense->serial, $row['serialNumber']); - $this->assertEquals($newLicense->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($newLicense->purchase_cost, $row['purchaseCost']); - $this->assertEquals($newLicense->order_number, $row['orderNumber']); - $this->assertEquals($newLicense->seats, $row['seats']); - $this->assertEquals($newLicense->notes, $row['notes']); - $this->assertEquals($newLicense->license_name, $row['licensedToName']); - $this->assertEquals($newLicense->license_email, $row['licensedToEmail']); - $this->assertEquals($newLicense->supplier->name, $row['supplierName']); - $this->assertEquals($newLicense->company->name, $row['companyName']); - $this->assertEquals($newLicense->category->name, $row['category']); - $this->assertEquals($newLicense->expiration_date->toDateString(), $row['expirationDate']); - $this->assertEquals($newLicense->maintained, $row['isMaintained'] === 'TRUE'); - $this->assertEquals($newLicense->reassignable, $row['isReassignAble'] === 'TRUE'); - $this->assertEquals($newLicense->purchase_order, ''); + $this->assertEquals($row['licenseName'], $newLicense->name); + $this->assertEquals($row['serialNumber'], $newLicense->serial); + $this->assertEquals($row['purchaseDate'], $newLicense->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $newLicense->purchase_cost); + $this->assertEquals($row['orderNumber'], $newLicense->order_number); + $this->assertEquals($row['seats'], $newLicense->seats); + $this->assertEquals($row['notes'], $newLicense->notes); + $this->assertEquals($row['licensedToName'], $newLicense->license_name); + $this->assertEquals($row['licensedToEmail'], $newLicense->license_email); + $this->assertEquals($row['supplierName'], $newLicense->supplier->name); + $this->assertEquals($row['companyName'], $newLicense->company->name); + $this->assertEquals($row['category'], $newLicense->category->name); + $this->assertEquals($row['expirationDate'], $newLicense->expiration_date->toDateString()); + $this->assertEquals($row['isMaintained'] === 'TRUE', $newLicense->maintained); + $this->assertEquals($row['isReassignAble'] === 'TRUE', $newLicense->reassignable); + $this->assertEquals('', $newLicense->purchase_order); $this->assertNull($newLicense->depreciation_id); $this->assertNull($newLicense->termination_date); $this->assertNull($newLicense->deprecate); @@ -155,7 +155,7 @@ class ImportLicenseTest extends ImportDataTestCase ->where('serial', $importFileBuilder->firstRow()['serialNumber']) ->sole(); - $this->assertEquals($newLicense->expiration_date->toDateString(), '2022-10-10'); + $this->assertEquals('2022-10-10', $newLicense->expiration_date->toDateString()); } #[Test] @@ -259,26 +259,26 @@ class ImportLicenseTest extends ImportDataTestCase ->where('serial', $row['serialNumber']) ->sole(); - $this->assertEquals($updatedLicense->name, $row['licenseName']); - $this->assertEquals($updatedLicense->serial, $row['serialNumber']); - $this->assertEquals($updatedLicense->purchase_date->toDateString(), $row['purchaseDate']); - $this->assertEquals($updatedLicense->purchase_cost, $row['purchaseCost']); - $this->assertEquals($updatedLicense->order_number, $row['orderNumber']); - $this->assertEquals($updatedLicense->seats, $row['seats']); - $this->assertEquals($updatedLicense->notes, $row['notes']); - $this->assertEquals($updatedLicense->license_name, $row['licensedToName']); - $this->assertEquals($updatedLicense->license_email, $row['licensedToEmail']); - $this->assertEquals($updatedLicense->supplier->name, $row['supplierName']); - $this->assertEquals($updatedLicense->company->name, $row['companyName']); - $this->assertEquals($updatedLicense->category->name, $row['category']); - $this->assertEquals($updatedLicense->expiration_date->toDateString(), $row['expirationDate']); - $this->assertEquals($updatedLicense->maintained, $row['isMaintained'] === 'TRUE'); - $this->assertEquals($updatedLicense->reassignable, $row['isReassignAble'] === 'TRUE'); - $this->assertEquals($updatedLicense->purchase_order, $license->purchase_order); - $this->assertEquals($updatedLicense->depreciation_id, $license->depreciation_id); - $this->assertEquals($updatedLicense->termination_date, $license->termination_date); - $this->assertEquals($updatedLicense->deprecate, $license->deprecate); - $this->assertEquals($updatedLicense->min_amt, $license->min_amt); + $this->assertEquals($row['licenseName'], $updatedLicense->name); + $this->assertEquals($row['serialNumber'], $updatedLicense->serial); + $this->assertEquals($row['purchaseDate'], $updatedLicense->purchase_date->toDateString()); + $this->assertEquals($row['purchaseCost'], $updatedLicense->purchase_cost); + $this->assertEquals($row['orderNumber'], $updatedLicense->order_number); + $this->assertEquals($row['seats'], $updatedLicense->seats); + $this->assertEquals($row['notes'], $updatedLicense->notes); + $this->assertEquals($row['licensedToName'], $updatedLicense->license_name); + $this->assertEquals($row['licensedToEmail'], $updatedLicense->license_email); + $this->assertEquals($row['supplierName'], $updatedLicense->supplier->name); + $this->assertEquals($row['companyName'], $updatedLicense->company->name); + $this->assertEquals($row['category'], $updatedLicense->category->name); + $this->assertEquals($row['expirationDate'], $updatedLicense->expiration_date->toDateString()); + $this->assertEquals($row['isMaintained'] === 'TRUE', $updatedLicense->maintained); + $this->assertEquals($row['isReassignAble'] === 'TRUE', $updatedLicense->reassignable); + $this->assertEquals($license->purchase_order, $updatedLicense->purchase_order); + $this->assertEquals($license->depreciation_id, $updatedLicense->depreciation_id); + $this->assertEquals($license->termination_date, $updatedLicense->termination_date); + $this->assertEquals($license->deprecate, $updatedLicense->deprecate); + $this->assertEquals($license->min_amt, $updatedLicense->min_amt); } #[Test] @@ -336,22 +336,22 @@ class ImportLicenseTest extends ImportDataTestCase ->where('serial', $row['companyName']) ->sole(); - $this->assertEquals($newLicense->name, $row['licenseName']); - $this->assertEquals($newLicense->serial, $row['companyName']); - $this->assertEquals($newLicense->purchase_date->toDateString(), $row['isMaintained']); - $this->assertEquals($newLicense->purchase_cost, $row['isReassignAble']); - $this->assertEquals($newLicense->order_number, $row['licensedToName']); - $this->assertEquals($newLicense->seats, $row['expirationDate']); - $this->assertEquals($newLicense->notes, $row['licensedToEmail']); - $this->assertEquals($newLicense->license_name, $row['seats']); - $this->assertEquals($newLicense->license_email, $row['serialNumber']); - $this->assertEquals($newLicense->supplier->name, $row['category']); - $this->assertEquals($newLicense->company->name, $row['notes']); - $this->assertEquals($newLicense->category->name, $row['manufacturerName']); - $this->assertEquals($newLicense->expiration_date->toDateString(), $row['orderNumber']); - $this->assertEquals($newLicense->maintained, $row['purchaseCost'] === 'TRUE'); - $this->assertEquals($newLicense->reassignable, $row['purchaseDate'] === 'TRUE'); - $this->assertEquals($newLicense->purchase_order, ''); + $this->assertEquals($row['licenseName'], $newLicense->name); + $this->assertEquals($row['companyName'], $newLicense->serial); + $this->assertEquals($row['isMaintained'], $newLicense->purchase_date->toDateString()); + $this->assertEquals($row['isReassignAble'], $newLicense->purchase_cost); + $this->assertEquals($row['licensedToName'], $newLicense->order_number); + $this->assertEquals($row['expirationDate'], $newLicense->seats); + $this->assertEquals($row['licensedToEmail'], $newLicense->notes); + $this->assertEquals($row['seats'], $newLicense->license_name); + $this->assertEquals($row['serialNumber'], $newLicense->license_email); + $this->assertEquals($row['category'], $newLicense->supplier->name); + $this->assertEquals($row['notes'], $newLicense->company->name); + $this->assertEquals($row['manufacturerName'], $newLicense->category->name); + $this->assertEquals($row['orderNumber'], $newLicense->expiration_date->toDateString()); + $this->assertEquals($row['purchaseCost'] === 'TRUE', $newLicense->maintained); + $this->assertEquals($row['purchaseDate'] === 'TRUE', $newLicense->reassignable); + $this->assertEquals('', $newLicense->purchase_order); $this->assertNull($newLicense->depreciation_id); $this->assertNull($newLicense->termination_date); $this->assertNull($newLicense->deprecate); diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php index 4415da3f12..6ac0070a19 100644 --- a/tests/Feature/Importing/Api/ImportUsersTest.php +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -78,21 +78,21 @@ class ImportUsersTest extends ImportDataTestCase Notification::assertNothingSent(); - $this->assertEquals($newUser->email, $row['email']); - $this->assertEquals($newUser->first_name, $row['firstName']); - $this->assertEquals($newUser->last_name, $row['lastName']); - $this->assertEquals($newUser->employee_num, $row['employeeNumber']); - $this->assertEquals($newUser->company->name, $row['companyName']); - $this->assertEquals($newUser->location->name, $row['location']); - $this->assertEquals($newUser->phone, $row['phoneNumber']); - $this->assertEquals($newUser->jobtitle, $row['position']); + $this->assertEquals($row['email'], $newUser->email); + $this->assertEquals($row['firstName'], $newUser->first_name); + $this->assertEquals($row['lastName'], $newUser->last_name); + $this->assertEquals($row['employeeNumber'], $newUser->employee_num); + $this->assertEquals($row['companyName'], $newUser->company->name); + $this->assertEquals($row['location'], $newUser->location->name); + $this->assertEquals($row['phoneNumber'], $newUser->phone); + $this->assertEquals($row['position'], $newUser->jobtitle); $this->assertTrue(Hash::isHashed($newUser->password)); - $this->assertEquals($newUser->website, ''); - $this->assertEquals($newUser->country, ''); - $this->assertEquals($newUser->address, ''); - $this->assertEquals($newUser->city, ''); - $this->assertEquals($newUser->state, ''); - $this->assertEquals($newUser->zip, ''); + $this->assertEquals('', $newUser->website); + $this->assertEquals('', $newUser->country); + $this->assertEquals('', $newUser->address); + $this->assertEquals('', $newUser->city); + $this->assertEquals('', $newUser->state); + $this->assertEquals('', $newUser->zip); $this->assertNull($newUser->permissions); $this->assertNull($newUser->avatar); $this->assertNull($newUser->notes); @@ -100,15 +100,15 @@ class ImportUsersTest extends ImportDataTestCase $this->assertNull($newUser->department_id); $this->assertNull($newUser->two_factor_secret); $this->assertNull($newUser->idap_import); - $this->assertEquals($newUser->locale, 'en-US'); - $this->assertEquals($newUser->show_in_list, 1); - $this->assertEquals($newUser->two_factor_enrolled, 0); - $this->assertEquals($newUser->two_factor_optin, 0); - $this->assertEquals($newUser->remote, 0); - $this->assertEquals($newUser->autoassign_licenses, 0); - $this->assertEquals($newUser->vip, 0); - $this->assertEquals($newUser->enable_sounds, 0); - $this->assertEquals($newUser->enable_confetti, 0); + $this->assertEquals('en-US', $newUser->locale); + $this->assertEquals(1, $newUser->show_in_list); + $this->assertEquals(0, $newUser->two_factor_enrolled); + $this->assertEquals(0, $newUser->two_factor_optin); + $this->assertEquals(0, $newUser->remote); + $this->assertEquals(0, $newUser->autoassign_licenses); + $this->assertEquals(0, $newUser->vip); + $this->assertEquals(0, $newUser->enable_sounds); + $this->assertEquals(0, $newUser->enable_confetti); $this->assertNull($newUser->created_by); $this->assertNull($newUser->start_date); $this->assertNull($newUser->end_date); @@ -118,7 +118,7 @@ class ImportUsersTest extends ImportDataTestCase $this->assertNull($newUser->last_login); $this->assertNull($newUser->persist_code); $this->assertNull($newUser->reset_password_code); - $this->assertEquals($newUser->activated, 0); + $this->assertEquals(0, $newUser->activated); } #[Test] @@ -169,7 +169,7 @@ class ImportUsersTest extends ImportDataTestCase $generatedUsername = User::generateFormattedNameFromFullName("{$row['firstName']} {$row['lastName']}")['username']; - $this->assertEquals($newUser->username, $generatedUsername); + $this->assertEquals($generatedUsername, $newUser->username); } #[Test] @@ -186,8 +186,8 @@ class ImportUsersTest extends ImportDataTestCase $userLocation = Location::query()->where('name', $importFileBuilder->firstRow()['location'])->sole(['id']); $this->assertEquals( - $assetsAssignedToUser->refresh()->location_id, - $userLocation->id + $userLocation->id, + $assetsAssignedToUser->refresh()->location_id ); } @@ -238,19 +238,19 @@ class ImportUsersTest extends ImportDataTestCase 'location_id', 'company_id', 'updated_at', 'phone', 'jobtitle' ]; - $this->assertEquals($updatedUser->email, $row['email']); - $this->assertEquals($updatedUser->first_name, $row['firstName']); - $this->assertEquals($updatedUser->last_name, $row['lastName']); - $this->assertEquals($updatedUser->employee_num, $row['employeeNumber']); - $this->assertEquals($updatedUser->company->name, $row['companyName']); - $this->assertEquals($updatedUser->location->name, $row['location']); - $this->assertEquals($updatedUser->phone, $row['phoneNumber']); - $this->assertEquals($updatedUser->jobtitle, $row['position']); + $this->assertEquals($row['email'], $updatedUser->email); + $this->assertEquals($row['firstName'], $updatedUser->first_name); + $this->assertEquals($row['lastName'], $updatedUser->last_name); + $this->assertEquals($row['employeeNumber'], $updatedUser->employee_num); + $this->assertEquals($row['companyName'], $updatedUser->company->name); + $this->assertEquals($row['location'], $updatedUser->location->name); + $this->assertEquals($row['phoneNumber'], $updatedUser->phone); + $this->assertEquals($row['position'], $updatedUser->jobtitle); $this->assertTrue(Hash::isHashed($updatedUser->password)); $this->assertEquals( - Arr::except($updatedUser->attributesToArray(), $updatedAttributes), Arr::except($user->attributesToArray(), $updatedAttributes), + Arr::except($updatedUser->attributesToArray(), $updatedAttributes), ); } @@ -295,21 +295,21 @@ class ImportUsersTest extends ImportDataTestCase ->where('username', $row['companyName']) ->sole(); - $this->assertEquals($newUser->email, $row['position']); - $this->assertEquals($newUser->first_name, $row['location']); - $this->assertEquals($newUser->last_name, $row['lastName']); - $this->assertEquals($newUser->jobtitle, $row['email']); - $this->assertEquals($newUser->employee_num, $row['phoneNumber']); - $this->assertEquals($newUser->company->name, $row['username']); - $this->assertEquals($newUser->location->name, $row['firstName']); - $this->assertEquals($newUser->phone, $row['employeeNumber']); + $this->assertEquals($row['position'], $newUser->email); + $this->assertEquals($row['location'], $newUser->first_name); + $this->assertEquals($row['lastName'], $newUser->last_name); + $this->assertEquals($row['email'], $newUser->jobtitle); + $this->assertEquals($row['phoneNumber'], $newUser->employee_num); + $this->assertEquals($row['username'], $newUser->company->name); + $this->assertEquals($row['firstName'], $newUser->location->name); + $this->assertEquals($row['employeeNumber'], $newUser->phone); $this->assertTrue(Hash::isHashed($newUser->password)); - $this->assertEquals($newUser->website, ''); - $this->assertEquals($newUser->country, ''); - $this->assertEquals($newUser->address, ''); - $this->assertEquals($newUser->city, ''); - $this->assertEquals($newUser->state, ''); - $this->assertEquals($newUser->zip, ''); + $this->assertEquals('', $newUser->website); + $this->assertEquals('', $newUser->country); + $this->assertEquals('', $newUser->address); + $this->assertEquals('', $newUser->city); + $this->assertEquals('', $newUser->state); + $this->assertEquals('', $newUser->zip); $this->assertNull($newUser->permissions); $this->assertNull($newUser->avatar); $this->assertNull($newUser->notes); @@ -317,15 +317,15 @@ class ImportUsersTest extends ImportDataTestCase $this->assertNull($newUser->department_id); $this->assertNull($newUser->two_factor_secret); $this->assertNull($newUser->idap_import); - $this->assertEquals($newUser->locale, 'en-US'); - $this->assertEquals($newUser->show_in_list, 1); - $this->assertEquals($newUser->two_factor_enrolled, 0); - $this->assertEquals($newUser->two_factor_optin, 0); - $this->assertEquals($newUser->remote, 0); - $this->assertEquals($newUser->autoassign_licenses, 0); - $this->assertEquals($newUser->vip, 0); - $this->assertEquals($newUser->enable_sounds, 0); - $this->assertEquals($newUser->enable_confetti, 0); + $this->assertEquals('en-US', $newUser->locale); + $this->assertEquals(1, $newUser->show_in_list); + $this->assertEquals(0, $newUser->two_factor_enrolled); + $this->assertEquals(0, $newUser->two_factor_optin); + $this->assertEquals(0, $newUser->remote); + $this->assertEquals(0, $newUser->autoassign_licenses); + $this->assertEquals(0, $newUser->vip); + $this->assertEquals(0, $newUser->enable_sounds); + $this->assertEquals(0, $newUser->enable_confetti); $this->assertNull($newUser->created_by); $this->assertNull($newUser->start_date); $this->assertNull($newUser->end_date); @@ -335,6 +335,6 @@ class ImportUsersTest extends ImportDataTestCase $this->assertNull($newUser->last_login); $this->assertNull($newUser->persist_code); $this->assertNull($newUser->reset_password_code); - $this->assertEquals($newUser->activated, 0); + $this->assertEquals(0, $newUser->activated); } } From bde05d6ed9840d6e712e0f4a785f9c9166f352fd Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 13:15:49 -0700 Subject: [PATCH 37/86] Use new() instead of times() --- database/factories/ImportFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/factories/ImportFactory.php b/database/factories/ImportFactory.php index 830c87fa76..0b0f79aa44 100644 --- a/database/factories/ImportFactory.php +++ b/database/factories/ImportFactory.php @@ -76,7 +76,7 @@ class ImportFactory extends Factory public function component() { return $this->state(function (array $attributes) { - $fileBuilder = Importing\ComponentsImportFileBuilder::times(); + $fileBuilder = Importing\ComponentsImportFileBuilder::new(); $attributes['name'] = "{$attributes['name']} Components"; $attributes['import_type'] = 'component'; From 983a25aa5f9004e05f27713fbef6e8f9302bb772 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 13:39:54 -0700 Subject: [PATCH 38/86] Simplify permission tests --- .../Feature/Importing/Api/ImportAccessoriesTest.php | 13 +++++-------- tests/Feature/Importing/Api/ImportAssetsTest.php | 12 ++++-------- .../Feature/Importing/Api/ImportComponentsTest.php | 13 +++++-------- .../Feature/Importing/Api/ImportConsumablesTest.php | 13 +++++-------- tests/Feature/Importing/Api/ImportLicenseTest.php | 13 +++++-------- tests/Feature/Importing/Api/ImportUsersTest.php | 12 ++++-------- 6 files changed, 28 insertions(+), 48 deletions(-) diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php index 27a80c0dd0..b4285775fc 100644 --- a/tests/Feature/Importing/Api/ImportAccessoriesTest.php +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\Company; +use App\Models\User; use Database\Factories\AccessoryFactory; use Database\Factories\CompanyFactory; use Illuminate\Support\Str; @@ -15,9 +16,10 @@ use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AccessoriesImportFileBuilder as ImportFileBuilder; -class ImportAccessoriesTest extends ImportDataTestCase +class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -31,14 +33,9 @@ class ImportAccessoriesTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportAccessories(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index d4b6ac52e7..70e61b41dc 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -19,9 +19,10 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AssetsImportFileBuilder as ImportFileBuilder; -class ImportAssetsTest extends ImportDataTestCase +class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -35,14 +36,9 @@ class ImportAssetsTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportAssets(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php index 1a68fbf1c2..c8a1209cf3 100644 --- a/tests/Feature/Importing/Api/ImportComponentsTest.php +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActionLog; use App\Models\Component; +use App\Models\User; use Database\Factories\ComponentFactory; use Illuminate\Support\Str; use Database\Factories\UserFactory; @@ -13,9 +14,10 @@ use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\ComponentsImportFileBuilder as ImportFileBuilder; -class ImportComponentsTest extends ImportDataTestCase +class ImportComponentsTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -29,14 +31,9 @@ class ImportComponentsTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportComponents(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php index 3962dea5d4..7647946dd9 100644 --- a/tests/Feature/Importing/Api/ImportConsumablesTest.php +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActivityLog; use App\Models\Consumable; +use App\Models\User; use Database\Factories\ConsumableFactory; use Illuminate\Support\Str; use Database\Factories\UserFactory; @@ -13,9 +14,10 @@ use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\ConsumablesImportFileBuilder as ImportFileBuilder; -class ImportConsumablesTest extends ImportDataTestCase +class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -29,14 +31,9 @@ class ImportConsumablesTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportConsumables(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php index 11865236f3..0d9e3e2a5d 100644 --- a/tests/Feature/Importing/Api/ImportLicenseTest.php +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActivityLog; use App\Models\License; +use App\Models\User; use Illuminate\Support\Str; use Database\Factories\UserFactory; use Database\Factories\ImportFactory; @@ -12,9 +13,10 @@ use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\LicensesImportFileBuilder as ImportFileBuilder; -class ImportLicenseTest extends ImportDataTestCase +class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -28,14 +30,9 @@ class ImportLicenseTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportLicenses(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php index 6ac0070a19..f506c0ac27 100644 --- a/tests/Feature/Importing/Api/ImportUsersTest.php +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -15,9 +15,10 @@ use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; +use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\UsersImportFileBuilder as ImportFileBuilder; -class ImportUsersTest extends ImportDataTestCase +class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequirement { use WithFaker; @@ -31,14 +32,9 @@ class ImportUsersTest extends ImportDataTestCase } #[Test] - #[DataProvider('permissionsTestData')] - public function onlyUserWithPermissionCanImportUsers(array|string $permissions): void + public function testRequiresPermission() { - $permissions = collect((array) $permissions) - ->map(fn (string $permission) => [$permission => '1']) - ->toJson(); - - $this->actingAsForApi(UserFactory::new()->create(['permissions' => $permissions])); + $this->actingAsForApi(User::factory()->create()); $this->importFileResponse(['import' => 44])->assertForbidden(); } From 88d549e7c5ee8fd385d897be557dbbac60a66f73 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 13:40:37 -0700 Subject: [PATCH 39/86] Remove unused data provider method --- .../Importing/Api/ImportDataTestCase.php | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/tests/Feature/Importing/Api/ImportDataTestCase.php b/tests/Feature/Importing/Api/ImportDataTestCase.php index ac39fab677..546b6c0f37 100644 --- a/tests/Feature/Importing/Api/ImportDataTestCase.php +++ b/tests/Feature/Importing/Api/ImportDataTestCase.php @@ -11,26 +11,4 @@ abstract class ImportDataTestCase extends TestCase { return $this->postJson(route('api.imports.importFile', $parameters), $parameters); } - - /** - * @todo Add more permissions. - */ - public static function permissionsTestData(): array - { - return [ - '`admin`' => ['admin'], - '`reports.view`' => ['reports.view'], - 'only `assets` permission' => [ - 'assets.view', - 'assets.create', - 'assets.edit', - 'assets.delete', - 'assets.checkout', - 'assets.checkin', - 'assets.audit', - 'assets.view.requestable', - 'assets.view.encrypted_custom_fields' - ] - ]; - } } From e21305377549886099d21b67f49d2abbccc42d91 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 13:59:58 -0700 Subject: [PATCH 40/86] Swap factory syntax --- app/Models/Import.php | 3 + .../Importing/Api/ImportAccessoriesTest.php | 69 +++++++++-------- .../Importing/Api/ImportAssetsTest.php | 77 ++++++++++--------- .../Importing/Api/ImportComponentsTest.php | 45 +++++------ .../Importing/Api/ImportConsumablesTest.php | 45 +++++------ .../Importing/Api/ImportLicenseTest.php | 49 ++++++------ .../Feature/Importing/Api/ImportUsersTest.php | 46 +++++------ 7 files changed, 172 insertions(+), 162 deletions(-) diff --git a/app/Models/Import.php b/app/Models/Import.php index 81728c8a5e..052612a197 100644 --- a/app/Models/Import.php +++ b/app/Models/Import.php @@ -2,10 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Import extends Model { + use HasFactory; + protected $casts = [ 'header_row' => 'array', 'first_row' => 'array', diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php index b4285775fc..e4ad8b3bef 100644 --- a/tests/Feature/Importing/Api/ImportAccessoriesTest.php +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\Company; +use App\Models\Import; use App\Models\User; use Database\Factories\AccessoryFactory; use Database\Factories\CompanyFactory; @@ -43,9 +44,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function userWithImportAccessoryPermissionCanImportAccessories(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->accessory()->create(); + $import = Import::factory()->accessory()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -55,9 +56,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio { $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertOk() ->assertExactJson([ @@ -108,9 +109,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -119,9 +120,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willFormatDate(): void { $importFileBuilder = ImportFileBuilder::new(['purchaseDate' => '2022/10/10']); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $accessory = Accessory::query() @@ -135,9 +136,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewCategoryWhenCategoryExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => Str::random()]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessories = Accessory::query() @@ -150,11 +151,11 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function willNotCreateNewAccessoryWhenAccessoryWithNameExists(): void { - $accessory = AccessoryFactory::new()->create(['name' => Str::random()]); + $accessory = Accessory::factory()->create(['name' => Str::random()]); $importFileBuilder = ImportFileBuilder::times(2)->replace(['itemName' => $accessory->name]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $probablyNewAccessories = Accessory::query() @@ -169,9 +170,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewCompanyWhenCompanyAlreadyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessories = Accessory::query() @@ -185,9 +186,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewLocationWhenLocationAlreadyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessories = Accessory::query() @@ -201,9 +202,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewManufacturerWhenManufacturerAlreadyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => $this->faker->company]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessories = Accessory::query() @@ -217,9 +218,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewSupplierWhenSupplierAlreadyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['supplierName' => $this->faker->company]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessories = Accessory::query() @@ -233,9 +234,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function whenColumnsAreMissingInImportFile(): void { $importFileBuilder = ImportFileBuilder::new()->forget(['minimumAmount', 'purchaseCost', 'purchaseDate']); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAccessory = Accessory::query() @@ -251,9 +252,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio public function whenRequiredColumnsAreMissingInImportFile(): void { $importFileBuilder = ImportFileBuilder::new()->forget(['itemName', 'quantity', 'category']); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() ->assertExactJson([ @@ -274,12 +275,12 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function updateAccessoryFromImport(): void { - $accessory = AccessoryFactory::new()->create(['name' => Str::random()])->refresh(); + $accessory = Accessory::factory()->create(['name' => Str::random()])->refresh(); $importFileBuilder = ImportFileBuilder::new(['itemName' => $accessory->name]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedAccessory = Accessory::query()->find($accessory->id); @@ -312,7 +313,7 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function whenImportFileContainsEmptyValues(): void { - $accessory = AccessoryFactory::new()->create(['name' => Str::random()]); + $accessory = Accessory::factory()->create(['name' => Str::random()]); $accessory->refresh(); $importFileBuilder = ImportFileBuilder::new([ @@ -332,9 +333,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio 'modelNumber' => '' ]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() ->assertExactJson([ @@ -352,7 +353,7 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder->replace(['itemName' => $accessory->name]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); @@ -382,9 +383,9 @@ class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissio ]; $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->accessory()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, 'column-mappings' => [ diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index 70e61b41dc..27fc723161 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -5,6 +5,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActionLog; use App\Models\Asset; use App\Models\CustomField; +use App\Models\Import; use App\Models\User; use App\Notifications\CheckoutAssetNotification; use Carbon\Carbon; @@ -46,9 +47,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function userWithImportAssetsPermissionCanImportAssets(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->asset()->create(); + $import = Import::factory()->asset()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -60,9 +61,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertOk() ->assertExactJson([ @@ -151,9 +152,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -161,11 +162,11 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function willNotCreateNewAssetWhenAssetWithSameTagAlreadyExists(): void { - $asset = AssetFactory::new()->create(['asset_tag' => $this->faker->uuid]); + $asset = Asset::factory()->create(['asset_tag' => $this->faker->uuid]); $importFileBuilder = ImportFileBuilder::times(4)->replace(['tag' => $asset->asset_tag]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() ->assertExactJson([ @@ -191,9 +192,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateNewCompanyWhenCompanyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -207,9 +208,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateNewLocationWhenLocationExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -223,9 +224,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateNewSupplierWhenSupplierExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['supplierName' => $this->faker->company]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -239,9 +240,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateNewManufacturerWhenManufacturerExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => $this->faker->company]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -256,9 +257,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateCategoryWhenCategoryExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -273,9 +274,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq public function willNotCreateNewAssetModelWhenAssetModelExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['model' => Str::random()]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAssets = Asset::query() @@ -295,9 +296,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq 'status' ]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAsset = Asset::query() @@ -318,9 +319,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq 'purchaseDate' => '2022/10/10' ]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAsset = Asset::query() @@ -339,9 +340,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq ->replace(['model' => '']); $rows = $importFileBuilder->all(); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() ->assertJson([ @@ -381,12 +382,12 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function updateAssetFromImport(): void { - $asset = AssetFactory::new()->create()->refresh(); + $asset = Asset::factory()->create()->refresh(); $importFileBuilder = ImportFileBuilder::times(1)->replace(['tag' => $asset->asset_tag]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedAsset = Asset::query() @@ -458,9 +459,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq ]; $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, @@ -546,7 +547,7 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $customField = CustomField::query()->where('name', 'Mac Address')->firstOrNew(); if (!$customField->exists) { - $customField = CustomFieldFactory::new()->macAddress()->create(['db_column' => '_snipeit_mac_address_1']); + $customField = CustomField::factory()->macAddress()->create(['db_column' => '_snipeit_mac_address_1']); } if ($customField->field_encrypted) { @@ -554,9 +555,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $customField->save(); } - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newAsset = Asset::query()->where('serial', $importFileBuilder->firstRow()['serialNumber'])->sole(); @@ -576,7 +577,7 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $customField = CustomField::query()->where('name', 'Mac Address')->firstOrNew(); if (!$customField->exists) { - $customField = CustomFieldFactory::new()->macAddress()->create(); + $customField = CustomField::factory()->macAddress()->create(); } if (!$customField->field_encrypted) { @@ -584,9 +585,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq $customField->save(); } - $import = ImportFactory::new()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->asset()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $asset = Asset::query()->where('serial', $importFileBuilder->firstRow()['serialNumber'])->sole(); diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php index c8a1209cf3..0eca70ae4c 100644 --- a/tests/Feature/Importing/Api/ImportComponentsTest.php +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActionLog; use App\Models\Component; +use App\Models\Import; use App\Models\User; use Database\Factories\ComponentFactory; use Illuminate\Support\Str; @@ -41,9 +42,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission #[Test] public function userWithImportAssetsPermissionCanImportComponents(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->component()->create(); + $import = Import::factory()->component()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -55,9 +56,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertOk() ->assertExactJson([ @@ -103,9 +104,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -113,16 +114,16 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission #[Test] public function willNotCreateNewComponentWhenComponentWithNameAndSerialNumberExists(): void { - $component = ComponentFactory::new()->create(); + $component = Component::factory()->create(); $importFileBuilder = ImportFileBuilder::times(4)->replace([ 'itemName' => $component->name, 'serialNumber' => $component->serial ]); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $probablyNewComponents = Component::query() @@ -138,9 +139,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission public function willNotCreateNewCompanyWhenCompanyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newComponents = Component::query() @@ -154,9 +155,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission public function willNotCreateNewLocationWhenLocationExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newComponents = Component::query() @@ -170,9 +171,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission public function willNotCreateNewCategoryWhenCategoryExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newComponents = Component::query() @@ -190,9 +191,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission ->forget(['quantity']); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() @@ -219,16 +220,16 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission #[Test] public function updateComponentFromImport(): void { - $component = ComponentFactory::new()->create(); + $component = Component::factory()->create(); $importFileBuilder = ImportFileBuilder::new([ 'itemName' => $component->name, 'serialNumber' => $component->serial ]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedComponent = Component::query() @@ -267,9 +268,9 @@ class ImportComponentsTest extends ImportDataTestCase implements TestsPermission ]; $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->component()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php index 7647946dd9..4b338629ac 100644 --- a/tests/Feature/Importing/Api/ImportConsumablesTest.php +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActivityLog; use App\Models\Consumable; +use App\Models\Import; use App\Models\User; use Database\Factories\ConsumableFactory; use Illuminate\Support\Str; @@ -41,9 +42,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function userWithImportAssetsPermissionCanImportConsumables(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->consumable()->create(); + $import = Import::factory()->consumable()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -55,9 +56,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertOk() ->assertExactJson([ @@ -105,9 +106,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -115,11 +116,11 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function willNotCreateNewConsumableWhenConsumableNameAlreadyExist(): void { - $consumable = ConsumableFactory::new()->create(['name' => Str::random()]); + $consumable = Consumable::factory()->create(['name' => Str::random()]); $importFileBuilder = ImportFileBuilder::new(['itemName' => $consumable->name]); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $probablyNewConsumables = Consumable::query() @@ -134,9 +135,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewCompanyWhenCompanyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newConsumables = Consumable::query() @@ -150,9 +151,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewLocationWhenLocationExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['location' => Str::random()]); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newConsumables = Consumable::query() @@ -166,9 +167,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio public function willNotCreateNewCategoryWhenCategoryExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => Str::random()]); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newConsumables = Consumable::query() @@ -184,9 +185,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder = ImportFileBuilder::new(['category' => ''])->forget(['quantity', 'name']); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() @@ -212,13 +213,13 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio #[Test] public function updateConsumableFromImport(): void { - $consumable = ConsumableFactory::new()->create(['name' => Str::random()]); + $consumable = Consumable::factory()->create(['name' => Str::random()]); $importFileBuilder = ImportFileBuilder::new(['itemName' => $consumable->name]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedConsumable = Consumable::query() @@ -262,9 +263,9 @@ class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissio $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->consumable()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php index 0d9e3e2a5d..99f770c28e 100644 --- a/tests/Feature/Importing/Api/ImportLicenseTest.php +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -3,6 +3,7 @@ namespace Tests\Feature\Importing\Api; use App\Models\Actionlog as ActivityLog; +use App\Models\Import; use App\Models\License; use App\Models\User; use Illuminate\Support\Str; @@ -40,9 +41,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe #[Test] public function userWithImportAssetsPermissionCanImportLicenses(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->license()->create(); + $import = Import::factory()->license()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -52,9 +53,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe { $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertOk() ->assertExactJson([ @@ -106,9 +107,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -116,16 +117,16 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe #[Test] public function willNotCreateNewLicenseWhenNameAndSerialNumberAlreadyExist(): void { - $license = LicenseFactory::new()->create(); + $license = License::factory()->create(); $importFileBuilder = ImportFileBuilder::times(4)->replace([ 'itemName' => $license->name, 'serialNumber' => $license->serial ]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $probablyNewLicenses = License::query() @@ -143,9 +144,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe 'expirationDate' => '2022/10/10' ]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newLicense = License::query() @@ -159,9 +160,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe public function willNotCreateNewCompanyWhenCompanyExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['companyName' => Str::random()]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newLicenses = License::query() @@ -175,9 +176,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe public function willNotCreateNewManufacturerWhenManufacturerExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['manufacturerName' => Str::random()]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newLicenses = License::query() @@ -191,9 +192,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe public function willNotCreateNewCategoryWhenCategoryExists(): void { $importFileBuilder = ImportFileBuilder::times(4)->replace(['category' => $this->faker->company]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newLicenses = License::query() @@ -211,9 +212,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe ->forget(['seats']); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() @@ -239,16 +240,16 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe #[Test] public function updateLicenseFromImport(): void { - $license = LicenseFactory::new()->create(); + $license = License::factory()->create(); $importFileBuilder = ImportFileBuilder::new([ 'licenseName' => $license->name, 'serialNumber' => $license->serial ]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedLicense = License::query() @@ -302,9 +303,9 @@ class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRe ]; $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->license()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php index f506c0ac27..6de7590902 100644 --- a/tests/Feature/Importing/Api/ImportUsersTest.php +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -2,6 +2,8 @@ namespace Tests\Feature\Importing\Api; +use App\Models\Asset; +use App\Models\Import; use App\Models\Location; use App\Models\User; use Database\Factories\AssetFactory; @@ -42,9 +44,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ #[Test] public function userWithImportAssetsPermissionCanImportUsers(): void { - $this->actingAsForApi(UserFactory::new()->canImport()->create()); + $this->actingAsForApi(User::factory()->canImport()->create()); - $import = ImportFactory::new()->users()->create(); + $import = Import::factory()->users()->create(); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -56,9 +58,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'send-welcome' => 1]) ->assertOk() ->assertExactJson([ @@ -125,9 +127,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ $importFileBuilder = new ImportFileBuilder([$row]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); $this->importFileResponse(['import' => $import->id])->assertOk(); } @@ -135,11 +137,11 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ #[Test] public function willNotCreateNewUserWhenUserWithUserNameAlreadyExist(): void { - $user = UserFactory::new()->create(['username' => Str::random()]); + $user = User::factory()->create(['username' => Str::random()]); $importFileBuilder = ImportFileBuilder::times(4)->replace(['username' => $user->username]); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $probablyNewUsers = User::query() @@ -154,9 +156,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ { $importFileBuilder = ImportFileBuilder::new()->forget('username'); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id])->assertOk(); $newUser = User::query() @@ -171,12 +173,12 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ #[Test] public function willUpdateLocationOfAllAssetsAssignedToUser(): void { - $user = UserFactory::new()->create(['username' => Str::random()]); - $assetsAssignedToUser = AssetFactory::new()->create(['assigned_to' => $user->id, 'assigned_type' => User::class]); + $user = User::factory()->create(['username' => Str::random()]); + $assetsAssignedToUser = Asset::factory()->create(['assigned_to' => $user->id, 'assigned_type' => User::class]); $importFileBuilder = ImportFileBuilder::new(['username' => $user->username]); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $userLocation = Location::query()->where('name', $importFileBuilder->firstRow()['location'])->sole(['id']); @@ -191,9 +193,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ public function whenRequiredColumnsAreMissingInImportFile(): void { $importFileBuilder = ImportFileBuilder::new(['firstName' => ''])->forget(['username']); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id]) ->assertInternalServerError() @@ -219,13 +221,13 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ #[Test] public function updateUserFromImport(): void { - $user = UserFactory::new()->create(['username' => Str::random()])->refresh(); + $user = User::factory()->create(['username' => Str::random()])->refresh(); $importFileBuilder = ImportFileBuilder::new(['username' => $user->username]); $row = $importFileBuilder->firstRow(); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse(['import' => $import->id, 'import-update' => true])->assertOk(); $updatedUser = User::query()->with(['company', 'location'])->find($user->id); @@ -267,9 +269,9 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ ]; $importFileBuilder = new ImportFileBuilder([$row]); - $import = ImportFactory::new()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); + $import = Import::factory()->users()->create(['file_path' => $importFileBuilder->saveToImportsDirectory()]); - $this->actingAsForApi(UserFactory::new()->superuser()->create()); + $this->actingAsForApi(User::factory()->superuser()->create()); $this->importFileResponse([ 'import' => $import->id, From 063ea1892b3fecdd52ad8cd353c39038a8087de7 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 15:02:03 -0700 Subject: [PATCH 41/86] Add trait to clean up files after test runs --- .../Importing/Api/ImportAccessoriesTest.php | 2 ++ .../Importing/Api/ImportAssetsTest.php | 2 ++ .../Importing/Api/ImportComponentsTest.php | 2 ++ .../Importing/Api/ImportConsumablesTest.php | 2 ++ .../Importing/Api/ImportLicenseTest.php | 2 ++ .../Feature/Importing/Api/ImportUsersTest.php | 3 +++ .../Support/Importing/CleansUpImportFiles.php | 20 +++++++++++++++++++ 7 files changed, 33 insertions(+) create mode 100644 tests/Support/Importing/CleansUpImportFiles.php diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php index e4ad8b3bef..91f72fe747 100644 --- a/tests/Feature/Importing/Api/ImportAccessoriesTest.php +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -19,9 +19,11 @@ use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AccessoriesImportFileBuilder as ImportFileBuilder; +use Tests\Support\Importing\CleansUpImportFiles; class ImportAccessoriesTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index 27fc723161..50c31d6d9f 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -22,9 +22,11 @@ use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AssetsImportFileBuilder as ImportFileBuilder; +use Tests\Support\Importing\CleansUpImportFiles; class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php index 0eca70ae4c..20f0e803da 100644 --- a/tests/Feature/Importing/Api/ImportComponentsTest.php +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -16,10 +16,12 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; +use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\ComponentsImportFileBuilder as ImportFileBuilder; class ImportComponentsTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php index 4b338629ac..d48486d19b 100644 --- a/tests/Feature/Importing/Api/ImportConsumablesTest.php +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -16,10 +16,12 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; +use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\ConsumablesImportFileBuilder as ImportFileBuilder; class ImportConsumablesTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php index 99f770c28e..fb4b9b932c 100644 --- a/tests/Feature/Importing/Api/ImportLicenseTest.php +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -15,10 +15,12 @@ use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; +use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\LicensesImportFileBuilder as ImportFileBuilder; class ImportLicenseTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php index 6de7590902..eb624e5609 100644 --- a/tests/Feature/Importing/Api/ImportUsersTest.php +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -7,6 +7,7 @@ use App\Models\Import; use App\Models\Location; use App\Models\User; use Database\Factories\AssetFactory; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Database\Factories\UserFactory; use Database\Factories\ImportFactory; @@ -18,10 +19,12 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Testing\TestResponse; use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; +use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\UsersImportFileBuilder as ImportFileBuilder; class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequirement { + use CleansUpImportFiles; use WithFaker; protected function importFileResponse(array $parameters = []): TestResponse diff --git a/tests/Support/Importing/CleansUpImportFiles.php b/tests/Support/Importing/CleansUpImportFiles.php new file mode 100644 index 0000000000..8e0cbc3108 --- /dev/null +++ b/tests/Support/Importing/CleansUpImportFiles.php @@ -0,0 +1,20 @@ +beforeApplicationDestroyed(function () use ($import) { + Storage::delete('private_uploads/imports/' . $import->file_path); + }); + }); + } +} From dfdd85abb17422380499d20fe4596a759ff56e4c Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 15:14:07 -0700 Subject: [PATCH 42/86] Remove unused imports --- tests/Feature/Importing/Api/ImportAccessoriesTest.php | 6 ------ tests/Feature/Importing/Api/ImportAssetsTest.php | 9 ++------- tests/Feature/Importing/Api/ImportComponentsTest.php | 8 ++------ tests/Feature/Importing/Api/ImportConsumablesTest.php | 8 ++------ tests/Feature/Importing/Api/ImportDataTestCase.php | 2 +- tests/Feature/Importing/Api/ImportLicenseTest.php | 8 ++------ tests/Feature/Importing/Api/ImportUsersTest.php | 9 ++------- 7 files changed, 11 insertions(+), 39 deletions(-) diff --git a/tests/Feature/Importing/Api/ImportAccessoriesTest.php b/tests/Feature/Importing/Api/ImportAccessoriesTest.php index 91f72fe747..aac9dabb1d 100644 --- a/tests/Feature/Importing/Api/ImportAccessoriesTest.php +++ b/tests/Feature/Importing/Api/ImportAccessoriesTest.php @@ -4,19 +4,13 @@ namespace Tests\Feature\Importing\Api; use App\Models\Accessory; use App\Models\Actionlog; -use App\Models\Company; use App\Models\Import; use App\Models\User; -use Database\Factories\AccessoryFactory; -use Database\Factories\CompanyFactory; use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AccessoriesImportFileBuilder as ImportFileBuilder; use Tests\Support\Importing\CleansUpImportFiles; diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index 50c31d6d9f..e001add381 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -9,17 +9,12 @@ use App\Models\Import; use App\Models\User; use App\Notifications\CheckoutAssetNotification; use Carbon\Carbon; -use Database\Factories\AssetFactory; -use Database\Factories\CustomFieldFactory; -use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; -use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\AssetsImportFileBuilder as ImportFileBuilder; use Tests\Support\Importing\CleansUpImportFiles; diff --git a/tests/Feature/Importing/Api/ImportComponentsTest.php b/tests/Feature/Importing/Api/ImportComponentsTest.php index 20f0e803da..376b5b32eb 100644 --- a/tests/Feature/Importing/Api/ImportComponentsTest.php +++ b/tests/Feature/Importing/Api/ImportComponentsTest.php @@ -6,15 +6,11 @@ use App\Models\Actionlog as ActionLog; use App\Models\Component; use App\Models\Import; use App\Models\User; -use Database\Factories\ComponentFactory; -use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; -use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\ComponentsImportFileBuilder as ImportFileBuilder; diff --git a/tests/Feature/Importing/Api/ImportConsumablesTest.php b/tests/Feature/Importing/Api/ImportConsumablesTest.php index d48486d19b..81bfdf4bf8 100644 --- a/tests/Feature/Importing/Api/ImportConsumablesTest.php +++ b/tests/Feature/Importing/Api/ImportConsumablesTest.php @@ -6,15 +6,11 @@ use App\Models\Actionlog as ActivityLog; use App\Models\Consumable; use App\Models\Import; use App\Models\User; -use Database\Factories\ConsumableFactory; -use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; -use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\ConsumablesImportFileBuilder as ImportFileBuilder; diff --git a/tests/Feature/Importing/Api/ImportDataTestCase.php b/tests/Feature/Importing/Api/ImportDataTestCase.php index 546b6c0f37..eaa2a8f03b 100644 --- a/tests/Feature/Importing/Api/ImportDataTestCase.php +++ b/tests/Feature/Importing/Api/ImportDataTestCase.php @@ -2,8 +2,8 @@ namespace Tests\Feature\Importing\Api; -use Tests\TestCase; use Illuminate\Testing\TestResponse; +use Tests\TestCase; abstract class ImportDataTestCase extends TestCase { diff --git a/tests/Feature/Importing/Api/ImportLicenseTest.php b/tests/Feature/Importing/Api/ImportLicenseTest.php index fb4b9b932c..0cd5fe447c 100644 --- a/tests/Feature/Importing/Api/ImportLicenseTest.php +++ b/tests/Feature/Importing/Api/ImportLicenseTest.php @@ -6,14 +6,10 @@ use App\Models\Actionlog as ActivityLog; use App\Models\Import; use App\Models\License; use App\Models\User; -use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; -use Database\Factories\LicenseFactory; -use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; +use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\LicensesImportFileBuilder as ImportFileBuilder; diff --git a/tests/Feature/Importing/Api/ImportUsersTest.php b/tests/Feature/Importing/Api/ImportUsersTest.php index eb624e5609..f8c0b7c743 100644 --- a/tests/Feature/Importing/Api/ImportUsersTest.php +++ b/tests/Feature/Importing/Api/ImportUsersTest.php @@ -6,18 +6,13 @@ use App\Models\Asset; use App\Models\Import; use App\Models\Location; use App\Models\User; -use Database\Factories\AssetFactory; -use Illuminate\Support\Facades\Storage; -use Illuminate\Support\Str; -use Database\Factories\UserFactory; -use Database\Factories\ImportFactory; -use PHPUnit\Framework\Attributes\Test; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use Tests\Concerns\TestsPermissionsRequirement; use Tests\Support\Importing\CleansUpImportFiles; use Tests\Support\Importing\UsersImportFileBuilder as ImportFileBuilder; From 8035326675e9a479c030687dc5a8079fd43e34f5 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Thu, 3 Oct 2024 16:53:19 -0700 Subject: [PATCH 43/86] Add test --- .../Feature/Importing/Api/GeneralImportTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/Feature/Importing/Api/GeneralImportTest.php diff --git a/tests/Feature/Importing/Api/GeneralImportTest.php b/tests/Feature/Importing/Api/GeneralImportTest.php new file mode 100644 index 0000000000..5c38dab7f3 --- /dev/null +++ b/tests/Feature/Importing/Api/GeneralImportTest.php @@ -0,0 +1,16 @@ +actingAsForApi(User::factory()->canImport()->create()); + + $this->importFileResponse(['import' => 9999, 'import-type' => 'accessory']) + ->assertStatusMessageIs('import-errors'); + } +} From f76da48448e06a6008751bcf9b7148b15722b1b8 Mon Sep 17 00:00:00 2001 From: Lewis Foster Date: Sat, 5 Oct 2024 18:27:42 +0100 Subject: [PATCH 44/86] Docker Env: Change trusted proxies to RFC1918 --- .env.docker | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.docker b/.env.docker index 9e50383014..4865f8e13a 100644 --- a/.env.docker +++ b/.env.docker @@ -97,7 +97,7 @@ API_TOKEN_EXPIRATION_YEARS=40 # -------------------------------------------- # OPTIONAL: SECURITY HEADER SETTINGS # -------------------------------------------- -APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1,172.0.0.0/8 +APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1,172.16.0.0/12 ALLOW_IFRAMING=false REFERRER_POLICY=same-origin ENABLE_CSP=false From 3f36d5f9b38d9adae796f01b930bccbe1b6406ed Mon Sep 17 00:00:00 2001 From: snipe Date: Mon, 7 Oct 2024 11:08:02 +0100 Subject: [PATCH 45/86] Removed duplicate CSS and removed line break before user section Signed-off-by: snipe --- resources/views/users/print.blade.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/resources/views/users/print.blade.php b/resources/views/users/print.blade.php index 2211b987bf..4ca442895b 100644 --- a/resources/views/users/print.blade.php +++ b/resources/views/users/print.blade.php @@ -36,11 +36,7 @@ @page { size: A4; } - - #start_of_user_section { - break-before: page; - } - + .print-logo { max-height: 40px; } @@ -51,13 +47,6 @@ } - From 8c9132aff9be01a90ac53b16d87303bd912b24b0 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Mon, 7 Oct 2024 14:22:49 -0700 Subject: [PATCH 46/86] Hide EULA text and button when nothing will be displayed --- resources/views/users/print.blade.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/resources/views/users/print.blade.php b/resources/views/users/print.blade.php index 4ca442895b..40575e7efc 100644 --- a/resources/views/users/print.blade.php +++ b/resources/views/users/print.blade.php @@ -373,8 +373,11 @@ @endif + @php + if (!empty($eulas)) $eulas = array_unique($eulas); + @endphp {{-- This may have been render at the top of the page if we're rendering more than one user... --}} - @if (count($users) === 1) + @if (count($users) === 1 && !empty($eulas))