From 00fc392a12eb5e17971fe389564593279f4bd3ec Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 12:41:04 +0100 Subject: [PATCH 01/25] Added missing traslations Signed-off-by: snipe --- resources/lang/en-US/general.php | 4 +++- resources/views/hardware/quickscan.blade.php | 2 +- resources/views/partials/more-info.blade.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index 5b1d0e9b3..98748282f 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -549,6 +549,8 @@ return [ 'license_seats' => ':count License Seat|:count License Seats', 'consumables' => ':count Consumable|:count Consumables', 'components' => ':count Component|:count Components', - ] + ], + 'more_info' => 'More Info', + 'quickscan_bulk_help' => 'Checking this box will edit the asset record to reflect this new location. Leaving it unchecked will simply note the location in the audit log. Note that if this asset is checked out, it will not change the location of the person, asset or location it is checked out to.', ]; diff --git a/resources/views/hardware/quickscan.blade.php b/resources/views/hardware/quickscan.blade.php index e042a6b5d..6124489f7 100644 --- a/resources/views/hardware/quickscan.blade.php +++ b/resources/views/hardware/quickscan.blade.php @@ -52,7 +52,7 @@ {{ trans('admin/hardware/form.asset_location') }} - + diff --git a/resources/views/partials/more-info.blade.php b/resources/views/partials/more-info.blade.php index 2f6c08b05..71dafb2a0 100644 --- a/resources/views/partials/more-info.blade.php +++ b/resources/views/partials/more-info.blade.php @@ -1,3 +1,3 @@ - + From a25263f8683456287cbc094e0b623246b541c921 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:29:49 +0100 Subject: [PATCH 02/25] Transfer files and acceptances on merge Signed-off-by: snipe --- .../Controllers/Users/BulkUsersController.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Users/BulkUsersController.php b/app/Http/Controllers/Users/BulkUsersController.php index d02856060..dd97d3c1a 100644 --- a/app/Http/Controllers/Users/BulkUsersController.php +++ b/app/Http/Controllers/Users/BulkUsersController.php @@ -317,7 +317,7 @@ class BulkUsersController extends Controller // Get the users $merge_into_user = User::find($request->input('merge_into_id')); - $users_to_merge = User::whereIn('id', $user_ids_to_merge)->with('assets', 'licenses', 'consumables','accessories')->get(); + $users_to_merge = User::whereIn('id', $user_ids_to_merge)->with('assets', 'licenses', 'consumables','accessories', 'uploads', 'acceptances')->get(); $admin = User::find(Auth::user()->id); // Walk users @@ -344,10 +344,20 @@ class BulkUsersController extends Controller } foreach ($user_to_merge->userlog as $log) { - $log->target_id = $user_to_merge->id; + $log->target_id = $merge_into_user->id; $log->save(); } + foreach ($user_to_merge->uploads as $upload) { + $upload->item_id = $merge_into_user->id; + $upload->save(); + } + + foreach ($user_to_merge->acceptances as $acceptance) { + $acceptance->item_id = $merge_into_user->id; + $acceptance->save(); + } + User::where('manager_id', '=', $user_to_merge->id)->update(['manager_id' => $merge_into_user->id]); foreach ($user_to_merge->managedLocations as $managedLocation) { @@ -356,7 +366,6 @@ class BulkUsersController extends Controller } $user_to_merge->delete(); - //$user_to_merge->save(); event(new UserMerged($user_to_merge, $merge_into_user, $admin)); From 2b2853a1830342994911d7a9cfdcaec6f255de7c Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:29:58 +0100 Subject: [PATCH 03/25] Added acceptance model Signed-off-by: snipe --- app/Models/User.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/Models/User.php b/app/Models/User.php index 30e32061e..339f15d03 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -481,8 +481,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo /** * Establishes the user -> uploads relationship * - * @todo I don't think we use this? - * * @author A. Gianotto * @since [v3.0] * @return \Illuminate\Database\Eloquent\Relations\Relation @@ -496,6 +494,21 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo ->orderBy('created_at', 'desc'); } + /** + * Establishes the user -> acceptances relationship + * + * @author A. Gianotto + * @since [v3.0] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function acceptances() + { + return $this->hasMany(\App\Models\Actionlog::class, 'target_id') + ->where('target_type', self::class) + ->where('action_type', '=', 'accepted') + ->orderBy('created_at', 'desc'); + } + /** * Establishes the user -> requested assets relationship * From d27a025347612a4d8478cc6d605e98c51f2e95b3 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:30:06 +0100 Subject: [PATCH 04/25] Added factories Signed-off-by: snipe --- database/factories/ActionlogFactory.php | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/database/factories/ActionlogFactory.php b/database/factories/ActionlogFactory.php index 1a4007888..fc359ab61 100644 --- a/database/factories/ActionlogFactory.php +++ b/database/factories/ActionlogFactory.php @@ -105,4 +105,51 @@ class ActionlogFactory extends Factory ]; }); } + + public function filesUploaded() + { + return $this->state(function () { + + return [ + 'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()), + 'action_type' => 'uploaded', + 'item_type' => User::class, + 'filename' => $this->faker->unixTime('now'), + ]; + }); + } + + public function acceptedSignature() + { + return $this->state(function () { + + $asset = Asset::factory()->create(); + + return [ + 'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()), + 'action_type' => 'accepted', + 'item_id' => $asset->id, + 'item_type' => Asset::class, + 'target_type' => User::class, + 'accept_signature' => $this->faker->unixTime('now'), + ]; + }); + } + + public function acceptedEula() + { + return $this->state(function () { + + $asset = Asset::factory()->create(); + + return [ + 'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()), + 'action_type' => 'accepted', + 'item_id' => $asset->id, + 'item_type' => Asset::class, + 'target_type' => User::class, + 'filename' => $this->faker->unixTime('now'), + ]; + }); + } } From ceaff7b645b4dd1646b166ff1a78d099e355f82c Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:30:11 +0100 Subject: [PATCH 05/25] Added tests Signed-off-by: snipe --- tests/Feature/Users/Ui/MergeUserTest.php | 92 ++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tests/Feature/Users/Ui/MergeUserTest.php diff --git a/tests/Feature/Users/Ui/MergeUserTest.php b/tests/Feature/Users/Ui/MergeUserTest.php new file mode 100644 index 000000000..0147e1db5 --- /dev/null +++ b/tests/Feature/Users/Ui/MergeUserTest.php @@ -0,0 +1,92 @@ +create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Asset::factory()->count(3)->assignedToUser($user1)->create(); + Asset::factory()->count(3)->assignedToUser($user2)->create(); + Asset::factory()->count(3)->assignedToUser($user_to_merge_into)->create(); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->assets->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->assets->count()); + + } + + public function testFilesAreTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Actionlog::factory()->count(3)->filesUploaded()->create(['item_id' => $user1->id]); + Actionlog::factory()->count(3)->filesUploaded()->create(['item_id' => $user2->id]); + Actionlog::factory()->count(3)->filesUploaded()->create(['item_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->uploads->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->uploads->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->uploads->count()); + + } + + public function testAcceptancesAreTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Actionlog::factory()->count(3)->acceptedSignature()->create(['target_id' => $user1->id]); + Actionlog::factory()->count(3)->acceptedSignature()->create(['target_id' => $user2->id]); + Actionlog::factory()->count(3)->acceptedSignature()->create(['target_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->acceptances->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->acceptances->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->acceptances->count()); + + } + +} From e34f3c7c2c54752953dc5259f995fb24feb0bf4b Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:32:41 +0100 Subject: [PATCH 06/25] Fixed typo Signed-off-by: snipe --- app/Models/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/User.php b/app/Models/User.php index 339f15d03..a93eb2656 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -498,7 +498,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo * Establishes the user -> acceptances relationship * * @author A. Gianotto - * @since [v3.0] + * @since [v7.0.7] * @return \Illuminate\Database\Eloquent\Relations\Relation */ public function acceptances() From 5488a4d118041ea833e8c8938f9b77974eb3468a Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 14:36:27 +0100 Subject: [PATCH 07/25] One more test Signed-off-by: snipe --- tests/Feature/Users/Ui/MergeUserTest.php | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/Feature/Users/Ui/MergeUserTest.php b/tests/Feature/Users/Ui/MergeUserTest.php index 0147e1db5..0ce4b715f 100644 --- a/tests/Feature/Users/Ui/MergeUserTest.php +++ b/tests/Feature/Users/Ui/MergeUserTest.php @@ -2,7 +2,10 @@ namespace Tests\Feature\Users\Ui; +use App\Models\Accessory; use App\Models\Asset; +use App\Models\License; +use App\Models\LicenseSeat; use App\Models\User; use App\Models\Actionlog; use Tests\TestCase; @@ -35,6 +38,60 @@ class MergeUserTest extends TestCase } + public function testLicensesAreTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + LicenseSeat::factory()->count(3)->create(['assigned_to' => $user1->id]); + LicenseSeat::factory()->count(3)->create(['assigned_to' => $user2->id]); + LicenseSeat::factory()->count(3)->create(['assigned_to' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->licenses->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->licenses->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->licenses->count()); + + } + + public function testAccessoriesTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Accessory::factory()->count(3)->checkedOutToUser($user1)->create(); + Accessory::factory()->count(3)->checkedOutToUser($user2)->create(); + Accessory::factory()->count(3)->checkedOutToUser($user_to_merge_into)->create(); + + $this->assertEquals(3, $user_to_merge_into->refresh()->accessories->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->accessories->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->accessories->count()); + + } + public function testFilesAreTransferredOnUserMerge() { $user1 = User::factory()->create(); From 574867536d88ccd897bb62c8519a5fa44d3c974a Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 19:41:34 +0100 Subject: [PATCH 08/25] Standardize query for merging Signed-off-by: snipe --- app/Console/Commands/MergeUsersByUsername.php | 14 +++++++++++++- app/Http/Controllers/Users/BulkUsersController.php | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/MergeUsersByUsername.php b/app/Console/Commands/MergeUsersByUsername.php index 390942708..f6a18aea4 100644 --- a/app/Console/Commands/MergeUsersByUsername.php +++ b/app/Console/Commands/MergeUsersByUsername.php @@ -51,7 +51,7 @@ class MergeUsersByUsername extends Command $bad_users = User::where('username', '=', trim($parts[0])) ->whereNull('deleted_at') - ->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations') + ->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations','uploads', 'acceptances') ->get(); @@ -105,6 +105,18 @@ class MergeUsersByUsername extends Command $managedLocation->save(); } + foreach ($bad_user->uploads as $upload) { + $this->info('Updating upload log record '.$upload->id.' to user '.$user->id); + $upload->item_id = $user->id; + $upload->save(); + } + + foreach ($bad_user->acceptances as $acceptance) { + $this->info('Updating acceptance log record '.$acceptance->id.' to user '.$user->id); + $acceptance->item_id = $user->id; + $acceptance->save(); + } + // Mark the user as deleted $this->info('Marking the user as deleted'); $bad_user->deleted_at = Carbon::now()->timestamp; diff --git a/app/Http/Controllers/Users/BulkUsersController.php b/app/Http/Controllers/Users/BulkUsersController.php index dd97d3c1a..a5b5f4d19 100644 --- a/app/Http/Controllers/Users/BulkUsersController.php +++ b/app/Http/Controllers/Users/BulkUsersController.php @@ -317,7 +317,7 @@ class BulkUsersController extends Controller // Get the users $merge_into_user = User::find($request->input('merge_into_id')); - $users_to_merge = User::whereIn('id', $user_ids_to_merge)->with('assets', 'licenses', 'consumables','accessories', 'uploads', 'acceptances')->get(); + $users_to_merge = User::whereIn('id', $user_ids_to_merge)->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations','uploads', 'acceptances')->get(); $admin = User::find(Auth::user()->id); // Walk users From 4635e9269dc3f538843d337ff3cf540c4d46527c Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:18:34 +0100 Subject: [PATCH 09/25] Added user update log factory Signed-off-by: snipe --- database/factories/ActionlogFactory.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/database/factories/ActionlogFactory.php b/database/factories/ActionlogFactory.php index fc359ab61..b1659ba86 100644 --- a/database/factories/ActionlogFactory.php +++ b/database/factories/ActionlogFactory.php @@ -152,4 +152,17 @@ class ActionlogFactory extends Factory ]; }); } + + public function logUserUpdate() + { + return $this->state(function () { + + return [ + 'created_at' => $this->faker->dateTimeBetween('-1 years', 'now', date_default_timezone_get()), + 'action_type' => 'update', + 'target_type' => User::class, + 'item_type' => User::class, + ]; + }); + } } From d66d6e70a6f9efe2c461a559e0e4f049fff87e9e Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:18:53 +0100 Subject: [PATCH 10/25] Added checkedOutToUser factory for consumables Signed-off-by: snipe --- database/factories/ConsumableFactory.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/database/factories/ConsumableFactory.php b/database/factories/ConsumableFactory.php index d9aec36af..67db205c0 100644 --- a/database/factories/ConsumableFactory.php +++ b/database/factories/ConsumableFactory.php @@ -7,6 +7,7 @@ use App\Models\Company; use App\Models\Consumable; use App\Models\Manufacturer; use App\Models\User; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\Factory; use App\Models\Supplier; @@ -116,4 +117,16 @@ class ConsumableFactory extends Factory $consumable->category->update(['require_acceptance' => 1]); }); } + + public function checkedOutToUser(User $user = null) + { + return $this->afterCreating(function (Consumable $consumable) use ($user) { + $consumable->users()->attach($consumable->id, [ + 'consumable_id' => $consumable->id, + 'created_at' => Carbon::now(), + 'user_id' => 1, + 'assigned_to' => $user->id ?? User::factory()->create()->id, + ]); + }); + } } From 1774952312c5874e4e6607d835212dcedc3e5c40 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:19:12 +0100 Subject: [PATCH 11/25] Added additional assertions Signed-off-by: snipe --- tests/Feature/Users/Ui/MergeUserTest.php | 73 +++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Users/Ui/MergeUserTest.php b/tests/Feature/Users/Ui/MergeUserTest.php index 0ce4b715f..d714f5967 100644 --- a/tests/Feature/Users/Ui/MergeUserTest.php +++ b/tests/Feature/Users/Ui/MergeUserTest.php @@ -4,7 +4,7 @@ namespace Tests\Feature\Users\Ui; use App\Models\Accessory; use App\Models\Asset; -use App\Models\License; +use App\Models\Consumable; use App\Models\LicenseSeat; use App\Models\User; use App\Models\Actionlog; @@ -35,6 +35,8 @@ class MergeUserTest extends TestCase $this->followRedirects($response)->assertSee('Success'); $this->assertNotEquals(3, $user_to_merge_into->refresh()->assets->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->assets->count()); + $this->assertEquals(0, $user1->refresh()->assets->count()); + $this->assertEquals(0, $user2->refresh()->assets->count()); } @@ -62,6 +64,8 @@ class MergeUserTest extends TestCase $this->followRedirects($response)->assertSee('Success'); $this->assertNotEquals(3, $user_to_merge_into->refresh()->licenses->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->licenses->count()); + $this->assertEquals(0, $user1->refresh()->licenses->count()); + $this->assertEquals(0, $user2->refresh()->licenses->count()); } @@ -89,6 +93,37 @@ class MergeUserTest extends TestCase $this->followRedirects($response)->assertSee('Success'); $this->assertNotEquals(3, $user_to_merge_into->refresh()->accessories->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->accessories->count()); + $this->assertEquals(0, $user1->refresh()->accessories->count()); + $this->assertEquals(0, $user2->refresh()->accessories->count()); + + } + + public function testConsumablesTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Consumable::factory()->count(3)->checkedOutToUser($user1)->create(); + Consumable::factory()->count(3)->checkedOutToUser($user2)->create(); + Consumable::factory()->count(3)->checkedOutToUser($user_to_merge_into)->create(); + + $this->assertEquals(3, $user_to_merge_into->refresh()->consumables->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->consumables->count()); + $this->assertEquals(9, $user_to_merge_into->refresh()->consumables->count()); + $this->assertEquals(0, $user1->refresh()->consumables->count()); + $this->assertEquals(0, $user2->refresh()->consumables->count()); } @@ -116,6 +151,8 @@ class MergeUserTest extends TestCase $this->followRedirects($response)->assertSee('Success'); $this->assertNotEquals(3, $user_to_merge_into->refresh()->uploads->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->uploads->count()); + $this->assertEquals(0, $user1->refresh()->uploads->count()); + $this->assertEquals(0, $user2->refresh()->uploads->count()); } @@ -143,7 +180,41 @@ class MergeUserTest extends TestCase $this->followRedirects($response)->assertSee('Success'); $this->assertNotEquals(3, $user_to_merge_into->refresh()->acceptances->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->acceptances->count()); + $this->assertEquals(0, $user1->refresh()->acceptances->count()); + $this->assertEquals(0, $user2->refresh()->acceptances->count()); } + public function testUserUpdateHistoryIsTransferredOnUserMerge() + { + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + $user_to_merge_into = User::factory()->create(); + + Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); + Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user2->id, 'item_id' => $user2->id]); + Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->userlog->count()); + + $response = $this->actingAs(User::factory()->editUsers()->viewUsers()->create()) + ->post(route('users.merge.save', $user1->id), + [ + 'ids_to_merge' => [$user1->id, $user2->id], + 'merge_into_id' => $user_to_merge_into->id + ]) + ->assertStatus(302) + ->assertRedirect(route('users.index')); + + $this->followRedirects($response)->assertSee('Success'); + $this->assertNotEquals(3, $user_to_merge_into->refresh()->userlog->count()); + + // This needs to be 2 more than the otherwise expected because the merge action itself is logged for the two merging users + $this->assertEquals(11, $user_to_merge_into->refresh()->userlog->count()); + $this->assertEquals(2, $user1->refresh()->userlog->count()); + $this->assertEquals(2, $user2->refresh()->userlog->count()); + + } + + } From dab4aced48cdb793d094b407cf5172cd3a3d73b6 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:50:09 +0100 Subject: [PATCH 12/25] Renamed test Signed-off-by: snipe --- .../Feature/Users/Ui/{MergeUserTest.php => MergeUsersTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/Feature/Users/Ui/{MergeUserTest.php => MergeUsersTest.php} (99%) diff --git a/tests/Feature/Users/Ui/MergeUserTest.php b/tests/Feature/Users/Ui/MergeUsersTest.php similarity index 99% rename from tests/Feature/Users/Ui/MergeUserTest.php rename to tests/Feature/Users/Ui/MergeUsersTest.php index d714f5967..27604fe7a 100644 --- a/tests/Feature/Users/Ui/MergeUserTest.php +++ b/tests/Feature/Users/Ui/MergeUsersTest.php @@ -11,7 +11,7 @@ use App\Models\Actionlog; use Tests\TestCase; -class MergeUserTest extends TestCase +class MergeUsersTest extends TestCase { public function testAssetsAreTransferredOnUserMerge() { From 50df7502025c345361eec5e30b781e23214027d2 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:50:23 +0100 Subject: [PATCH 13/25] Add merge event Signed-off-by: snipe --- app/Console/Commands/MergeUsersByUsername.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Console/Commands/MergeUsersByUsername.php b/app/Console/Commands/MergeUsersByUsername.php index f6a18aea4..0c5e966ab 100644 --- a/app/Console/Commands/MergeUsersByUsername.php +++ b/app/Console/Commands/MergeUsersByUsername.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Events\UserMerged; use App\Models\User; use Carbon\Carbon; use Illuminate\Console\Command; @@ -121,6 +122,10 @@ class MergeUsersByUsername extends Command $this->info('Marking the user as deleted'); $bad_user->deleted_at = Carbon::now()->timestamp; $bad_user->save(); + + event(new UserMerged($bad_user, $user, null)); + + } } } From ec24120d2a70c2bfe81c8b6bdde62d2bf4230ce6 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:50:35 +0100 Subject: [PATCH 14/25] Allow admin to be nullable (for cli) Signed-off-by: snipe --- app/Events/UserMerged.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Events/UserMerged.php b/app/Events/UserMerged.php index b045fdef0..3a7f4d6a2 100644 --- a/app/Events/UserMerged.php +++ b/app/Events/UserMerged.php @@ -15,7 +15,7 @@ class UserMerged * * @return void */ - public function __construct(User $from_user, User $to_user, User $admin) + public function __construct(User $from_user, User $to_user, ?User $admin) { $this->merged_from = $from_user; $this->merged_to = $to_user; From 1553ba5630aab368a421f30541809cf2f0aa4135 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:52:12 +0100 Subject: [PATCH 15/25] Added null coalescence for admin id in case via cli Signed-off-by: snipe --- app/Listeners/LogListener.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Listeners/LogListener.php b/app/Listeners/LogListener.php index 57eee03f1..b44fcdfcb 100644 --- a/app/Listeners/LogListener.php +++ b/app/Listeners/LogListener.php @@ -111,7 +111,7 @@ class LogListener $logaction->target_type = User::class; $logaction->action_type = 'merged'; $logaction->note = trans('general.merged_log_this_user_from', $to_from_array); - $logaction->user_id = $event->admin->id; + $logaction->user_id = $event->admin->id ?? null; $logaction->save(); // Add a record to the users being merged TO @@ -122,7 +122,7 @@ class LogListener $logaction->item_type = User::class; $logaction->action_type = 'merged'; $logaction->note = trans('general.merged_log_this_user_into', $to_from_array); - $logaction->user_id = $event->admin->id; + $logaction->user_id = $event->admin->id ?? null; $logaction->save(); From eff1980df5a12389ee839c0705fe7be9ca4c66ad Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:52:22 +0100 Subject: [PATCH 16/25] Added console test Signed-off-by: snipe --- tests/Feature/Console/MergeUsersTest.php | 143 +++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 tests/Feature/Console/MergeUsersTest.php diff --git a/tests/Feature/Console/MergeUsersTest.php b/tests/Feature/Console/MergeUsersTest.php new file mode 100644 index 000000000..1171dc22a --- /dev/null +++ b/tests/Feature/Console/MergeUsersTest.php @@ -0,0 +1,143 @@ +create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Asset::factory()->count(3)->assignedToUser($user1)->create(); + Asset::factory()->count(3)->assignedToUser($user_to_merge_into)->create(); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->assets->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->assets->count()); + $this->assertEquals(0, $user1->refresh()->assets->count()); + + } + + public function testLicensesAreTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + LicenseSeat::factory()->count(3)->create(['assigned_to' => $user1->id]); + LicenseSeat::factory()->count(3)->create(['assigned_to' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->licenses->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->licenses->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->licenses->count()); + $this->assertEquals(0, $user1->refresh()->licenses->count()); + + } + + public function testAccessoriesTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Accessory::factory()->count(3)->checkedOutToUser($user1)->create(); + Accessory::factory()->count(3)->checkedOutToUser($user_to_merge_into)->create(); + + $this->assertEquals(3, $user_to_merge_into->refresh()->accessories->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->accessories->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->accessories->count()); + $this->assertEquals(0, $user1->refresh()->accessories->count()); + + } + + public function testConsumablesTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Consumable::factory()->count(3)->checkedOutToUser($user1)->create(); + Consumable::factory()->count(3)->checkedOutToUser($user_to_merge_into)->create(); + + $this->assertEquals(3, $user_to_merge_into->refresh()->consumables->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->consumables->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->consumables->count()); + $this->assertEquals(0, $user1->refresh()->consumables->count()); + + } + + public function testFilesAreTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Actionlog::factory()->count(3)->filesUploaded()->create(['item_id' => $user1->id]); + Actionlog::factory()->count(3)->filesUploaded()->create(['item_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->uploads->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->uploads->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->uploads->count()); + $this->assertEquals(0, $user1->refresh()->uploads->count()); + + } + + public function testAcceptancesAreTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Actionlog::factory()->count(3)->acceptedSignature()->create(['target_id' => $user1->id]); + Actionlog::factory()->count(3)->acceptedSignature()->create(['target_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->acceptances->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->acceptances->count()); + $this->assertEquals(6, $user_to_merge_into->refresh()->acceptances->count()); + $this->assertEquals(0, $user1->refresh()->acceptances->count()); + + } + + public function testUserUpdateHistoryIsTransferredOnUserMerge(): void + { + $user1 = User::factory()->create(['username' => 'user1']); + $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); + + Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); + Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); + + $this->assertEquals(3, $user_to_merge_into->refresh()->userlog->count()); + + $this->artisan('snipeit:merge-users')->assertExitCode(0); + + $this->assertNotEquals(3, $user_to_merge_into->refresh()->userlog->count()); + + // This needs to be 2 more than the otherwise expected because the merge action itself is logged for the two merging users + $this->assertEquals(11, $user_to_merge_into->refresh()->userlog->count()); + $this->assertEquals(2, $user1->refresh()->userlog->count()); + + } + + +} From 9211c8d3b198db66b5a335e54f834e89b6261d93 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 20:57:21 +0100 Subject: [PATCH 17/25] Fixed test Signed-off-by: snipe --- tests/Feature/Console/MergeUsersTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Console/MergeUsersTest.php b/tests/Feature/Console/MergeUsersTest.php index 1171dc22a..e7a34159b 100644 --- a/tests/Feature/Console/MergeUsersTest.php +++ b/tests/Feature/Console/MergeUsersTest.php @@ -133,9 +133,9 @@ class MergeUsersTest extends TestCase $this->assertNotEquals(3, $user_to_merge_into->refresh()->userlog->count()); - // This needs to be 2 more than the otherwise expected because the merge action itself is logged for the two merging users - $this->assertEquals(11, $user_to_merge_into->refresh()->userlog->count()); - $this->assertEquals(2, $user1->refresh()->userlog->count()); + // This needs to be more than the otherwise expected because the merge action itself is logged for the two merging users + $this->assertEquals(7, $user_to_merge_into->refresh()->userlog->count()); + $this->assertEquals(1, $user1->refresh()->userlog->count()); } From aefaabdb1a788f1108d2980e02909820fca81abc Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 21:40:43 +0100 Subject: [PATCH 18/25] Removed non-counts from allowed array Signed-off-by: snipe --- app/Http/Controllers/Api/UsersController.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 3374f1907..6a96fb728 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -247,10 +247,6 @@ class UsersController extends Controller 'jobtitle', 'username', 'employee_num', - 'assets', - 'accessories', - 'consumables', - 'licenses', 'groups', 'activated', 'created_at', From ca57f6de85782604f4585b5abd83671a1f07f3cc Mon Sep 17 00:00:00 2001 From: akemidx Date: Wed, 3 Jul 2024 17:07:50 -0400 Subject: [PATCH 19/25] adding in item=>asset, missed in first commit --- .../Controllers/Assets/AssetsController.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index bf3a3ec3a..82c68eb01 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -906,6 +906,25 @@ class AssetsController extends Controller $asset->location_id = $request->input('location_id'); } + if (($asset->model->fieldset)) { + foreach ($asset->model->fieldset->fields as $field) { + if ($field->field_encrypted == '1') { + if (Gate::allows('admin')) { + if (is_array($request->input($field->db_column))) { + $asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column))); + } else { + $asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column)); + } + } + } else { + if (is_array($request->input($field->db_column))) { + $asset->{$field->db_column} = implode(', ', $request->input($field->db_column)); + } else { + $asset->{$field->db_column} = $request->input($field->db_column); + } + } + } + } /** * Invoke Watson Validating to check the asset itself and check to make sure it saved correctly. From 17a6335d133ad59acd2289fc8541cb2a6a44b679 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 22:12:06 +0100 Subject: [PATCH 20/25] Added test Signed-off-by: snipe --- tests/Feature/Users/Api/UserSearchTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/Feature/Users/Api/UserSearchTest.php b/tests/Feature/Users/Api/UserSearchTest.php index 2b1d55797..fba18e67e 100644 --- a/tests/Feature/Users/Api/UserSearchTest.php +++ b/tests/Feature/Users/Api/UserSearchTest.php @@ -144,4 +144,15 @@ class UserSearchTest extends TestCase 'User index contains unexpected user from another company' ); } + + public function testUsersIndexWhenInvalidSortFieldIsPassed() + { + $this->actingAsForApi(User::factory()->viewUsers()->create()) + ->getJson(route('api.users.index', [ + 'sort' => 'assets', + ])) + ->assertOk() + ->assertStatus(200) + ->json(); + } } From a6690493b0f6ef4b3b61bf94eb2be6e6af62683b Mon Sep 17 00:00:00 2001 From: spencerrlongg Date: Wed, 3 Jul 2024 16:12:55 -0500 Subject: [PATCH 21/25] resolved --- app/Livewire/PersonalAccessTokens.php | 2 +- resources/views/livewire/personal-access-tokens.blade.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Livewire/PersonalAccessTokens.php b/app/Livewire/PersonalAccessTokens.php index 2d2f56662..69bf1d28a 100644 --- a/app/Livewire/PersonalAccessTokens.php +++ b/app/Livewire/PersonalAccessTokens.php @@ -49,6 +49,6 @@ class PersonalAccessTokens extends Component { //this needs safety (though the scope of auth::user might kind of do it...) //seems like it does, test more - Auth::user()->tokens()->find($tokenId)->delete(); + Auth::user()->tokens()->find($tokenId)?->delete(); } } diff --git a/resources/views/livewire/personal-access-tokens.blade.php b/resources/views/livewire/personal-access-tokens.blade.php index 848e4ca49..8cae9d264 100644 --- a/resources/views/livewire/personal-access-tokens.blade.php +++ b/resources/views/livewire/personal-access-tokens.blade.php @@ -48,7 +48,8 @@ - + From 5e15cc3bbe4267d7d164e126af497a7789b69707 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 22:18:31 +0100 Subject: [PATCH 22/25] Added markIncompleteIfSqlite() method Signed-off-by: snipe --- tests/Feature/Users/Api/UserSearchTest.php | 2 ++ tests/Support/CanSkipTests.php | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/tests/Feature/Users/Api/UserSearchTest.php b/tests/Feature/Users/Api/UserSearchTest.php index fba18e67e..dc0ffdc80 100644 --- a/tests/Feature/Users/Api/UserSearchTest.php +++ b/tests/Feature/Users/Api/UserSearchTest.php @@ -147,6 +147,8 @@ class UserSearchTest extends TestCase public function testUsersIndexWhenInvalidSortFieldIsPassed() { + $this->markIncompleteIfSqlite('This test is not compatible with SQLite'); + $this->actingAsForApi(User::factory()->viewUsers()->create()) ->getJson(route('api.users.index', [ 'sort' => 'assets', diff --git a/tests/Support/CanSkipTests.php b/tests/Support/CanSkipTests.php index 2a1eec10f..b29fdf88c 100644 --- a/tests/Support/CanSkipTests.php +++ b/tests/Support/CanSkipTests.php @@ -10,4 +10,11 @@ trait CanSkipTests $this->markTestIncomplete($message); } } + + public function markIncompleteIfSqlite($message = 'Test skipped due to database driver being sqlite.') + { + if (config('database.default') === 'sqlite') { + $this->markTestIncomplete($message); + } + } } From 9f1e59cf7875f6c451b9f416875e3ac4930d27fd Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 23:01:41 +0100 Subject: [PATCH 23/25] =?UTF-8?q?Marcus=E2=80=99=20nitpicks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: snipe --- database/factories/ActionlogFactory.php | 2 +- database/factories/ConsumableFactory.php | 2 +- tests/Feature/Console/MergeUsersTest.php | 14 +++----------- tests/Feature/Users/Ui/MergeUsersTest.php | 13 +++---------- 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/database/factories/ActionlogFactory.php b/database/factories/ActionlogFactory.php index b1659ba86..a88166d14 100644 --- a/database/factories/ActionlogFactory.php +++ b/database/factories/ActionlogFactory.php @@ -153,7 +153,7 @@ class ActionlogFactory extends Factory }); } - public function logUserUpdate() + public function userUpdated() { return $this->state(function () { diff --git a/database/factories/ConsumableFactory.php b/database/factories/ConsumableFactory.php index 67db205c0..ca3a2faf9 100644 --- a/database/factories/ConsumableFactory.php +++ b/database/factories/ConsumableFactory.php @@ -124,7 +124,7 @@ class ConsumableFactory extends Factory $consumable->users()->attach($consumable->id, [ 'consumable_id' => $consumable->id, 'created_at' => Carbon::now(), - 'user_id' => 1, + 'user_id' => User::factory()->create()->id, 'assigned_to' => $user->id ?? User::factory()->create()->id, ]); }); diff --git a/tests/Feature/Console/MergeUsersTest.php b/tests/Feature/Console/MergeUsersTest.php index e7a34159b..4c43e6293 100644 --- a/tests/Feature/Console/MergeUsersTest.php +++ b/tests/Feature/Console/MergeUsersTest.php @@ -1,6 +1,6 @@ artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->assets->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->assets->count()); $this->assertEquals(0, $user1->refresh()->assets->count()); @@ -41,7 +40,6 @@ class MergeUsersTest extends TestCase $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->licenses->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->licenses->count()); $this->assertEquals(0, $user1->refresh()->licenses->count()); @@ -59,7 +57,6 @@ class MergeUsersTest extends TestCase $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->accessories->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->accessories->count()); $this->assertEquals(0, $user1->refresh()->accessories->count()); @@ -77,7 +74,6 @@ class MergeUsersTest extends TestCase $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->consumables->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->consumables->count()); $this->assertEquals(0, $user1->refresh()->consumables->count()); @@ -95,7 +91,6 @@ class MergeUsersTest extends TestCase $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->uploads->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->uploads->count()); $this->assertEquals(0, $user1->refresh()->uploads->count()); @@ -113,7 +108,6 @@ class MergeUsersTest extends TestCase $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->acceptances->count()); $this->assertEquals(6, $user_to_merge_into->refresh()->acceptances->count()); $this->assertEquals(0, $user1->refresh()->acceptances->count()); @@ -124,15 +118,13 @@ class MergeUsersTest extends TestCase $user1 = User::factory()->create(['username' => 'user1']); $user_to_merge_into = User::factory()->create(['username' => 'user1@example.com']); - Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); - Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); + Actionlog::factory()->count(3)->userUpdated()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); + Actionlog::factory()->count(3)->userUpdated()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); $this->assertEquals(3, $user_to_merge_into->refresh()->userlog->count()); $this->artisan('snipeit:merge-users')->assertExitCode(0); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->userlog->count()); - // This needs to be more than the otherwise expected because the merge action itself is logged for the two merging users $this->assertEquals(7, $user_to_merge_into->refresh()->userlog->count()); $this->assertEquals(1, $user1->refresh()->userlog->count()); diff --git a/tests/Feature/Users/Ui/MergeUsersTest.php b/tests/Feature/Users/Ui/MergeUsersTest.php index 27604fe7a..a9ae11171 100644 --- a/tests/Feature/Users/Ui/MergeUsersTest.php +++ b/tests/Feature/Users/Ui/MergeUsersTest.php @@ -33,7 +33,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->assets->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->assets->count()); $this->assertEquals(0, $user1->refresh()->assets->count()); $this->assertEquals(0, $user2->refresh()->assets->count()); @@ -62,7 +61,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->licenses->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->licenses->count()); $this->assertEquals(0, $user1->refresh()->licenses->count()); $this->assertEquals(0, $user2->refresh()->licenses->count()); @@ -91,7 +89,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->accessories->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->accessories->count()); $this->assertEquals(0, $user1->refresh()->accessories->count()); $this->assertEquals(0, $user2->refresh()->accessories->count()); @@ -120,7 +117,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->consumables->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->consumables->count()); $this->assertEquals(0, $user1->refresh()->consumables->count()); $this->assertEquals(0, $user2->refresh()->consumables->count()); @@ -149,7 +145,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->uploads->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->uploads->count()); $this->assertEquals(0, $user1->refresh()->uploads->count()); $this->assertEquals(0, $user2->refresh()->uploads->count()); @@ -178,7 +173,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->acceptances->count()); $this->assertEquals(9, $user_to_merge_into->refresh()->acceptances->count()); $this->assertEquals(0, $user1->refresh()->acceptances->count()); $this->assertEquals(0, $user2->refresh()->acceptances->count()); @@ -191,9 +185,9 @@ class MergeUsersTest extends TestCase $user2 = User::factory()->create(); $user_to_merge_into = User::factory()->create(); - Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); - Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user2->id, 'item_id' => $user2->id]); - Actionlog::factory()->count(3)->logUserUpdate()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); + Actionlog::factory()->count(3)->userUpdated()->create(['target_id' => $user1->id, 'item_id' => $user1->id]); + Actionlog::factory()->count(3)->userUpdated()->create(['target_id' => $user2->id, 'item_id' => $user2->id]); + Actionlog::factory()->count(3)->userUpdated()->create(['target_id' => $user_to_merge_into->id, 'item_id' => $user_to_merge_into->id]); $this->assertEquals(3, $user_to_merge_into->refresh()->userlog->count()); @@ -207,7 +201,6 @@ class MergeUsersTest extends TestCase ->assertRedirect(route('users.index')); $this->followRedirects($response)->assertSee('Success'); - $this->assertNotEquals(3, $user_to_merge_into->refresh()->userlog->count()); // This needs to be 2 more than the otherwise expected because the merge action itself is logged for the two merging users $this->assertEquals(11, $user_to_merge_into->refresh()->userlog->count()); From 59f66051f82fe5943d25e2ebc78104a1bd9b1071 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 23:18:37 +0100 Subject: [PATCH 24/25] More eager loading Signed-off-by: snipe --- app/Http/Controllers/Users/BulkUsersController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Users/BulkUsersController.php b/app/Http/Controllers/Users/BulkUsersController.php index a5b5f4d19..efac5a8d3 100644 --- a/app/Http/Controllers/Users/BulkUsersController.php +++ b/app/Http/Controllers/Users/BulkUsersController.php @@ -42,7 +42,7 @@ class BulkUsersController extends Controller // Get the list of affected users $user_raw_array = request('ids'); $users = User::whereIn('id', $user_raw_array) - ->with('groups', 'assets', 'licenses', 'accessories')->get(); + ->with('assets', 'manager', 'userlog', 'licenses', 'consumables', 'accessories', 'managedLocations','uploads', 'acceptances')->get(); // bulk edit, display the bulk edit form if ($request->input('bulk_actions') == 'edit') { From 00715962744c7f59340f91f233cb530ca737a61b Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 3 Jul 2024 23:18:43 +0100 Subject: [PATCH 25/25] Added upload count Signed-off-by: snipe --- resources/views/users/confirm-merge.blade.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/resources/views/users/confirm-merge.blade.php b/resources/views/users/confirm-merge.blade.php index 45635dc4f..f2658cbb6 100644 --- a/resources/views/users/confirm-merge.blade.php +++ b/resources/views/users/confirm-merge.blade.php @@ -66,6 +66,10 @@ {{ trans('general.consumables') }} + + + {{ trans('general.files') }} + @@ -93,16 +97,19 @@ @endforeach - {{ number_format($user->assets()->count()) }} + {{ number_format($user->assets->count()) }} - {{ number_format($user->accessories()->count()) }} + {{ number_format($user->accessories->count()) }} - {{ number_format($user->licenses()->count()) }} + {{ number_format($user->licenses->count()) }} - {{ number_format($user->consumables()->count()) }} + {{ number_format($user->consumables->count()) }} + + + {{ number_format($user->uploads->count()) }} @endforeach