From c7f2acf2c6d41d4ec909861ef799fa59d188f57e Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Aug 2023 11:39:38 -0700 Subject: [PATCH 01/14] removes encrypted info from change log, renames asset_eol_date in the change log --- .../Transformers/ActionlogsTransformer.php | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 2a592e9c8..30468c85e 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -52,12 +52,18 @@ class ActionlogsTransformer if ($meta_array) { foreach ($meta_array as $fieldname => $fieldata) { - $clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old); - $clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new); - } + if ((strlen($this->clean_field($fieldata->old)) == 200) || (strlen($this->clean_field($fieldata->new))== 200)) { + $clean_meta[$fieldname]['old'] = "encrypted"; + $clean_meta[$fieldname]['new'] = "encrypted"; + } else { + $clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old); + $clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new); + } + } + \Log::info("Clean Meta is: " . print_r($clean_meta, true)); + $clean_meta = $this->changedInfo($clean_meta); } - $clean_meta= $this->changedInfo($clean_meta); } $file_url = ''; @@ -120,7 +126,7 @@ class ActionlogsTransformer 'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null, 'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'), ]; - //\Log::info("Clean Meta is: ".print_r($clean_meta,true)); +// \Log::info("Clean Meta is: ".print_r($clean_meta,true)); //dd($array); return $array; @@ -176,6 +182,11 @@ class ActionlogsTransformer $clean_meta['Supplier'] = $clean_meta['supplier_id']; unset($clean_meta['supplier_id']); } + if(array_key_exists('asset_eol_date', $clean_meta)) { + + $clean_meta['EOL date'] = $clean_meta['asset_eol_date']; + unset($clean_meta['asset_eol_date']); + } return $clean_meta; From 9e438c3ed04da12b6df639c1e62be620837117dd Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Aug 2023 12:34:45 -0700 Subject: [PATCH 02/14] eager loaded changedInfo queries, reworked encrypted data change log changes --- .../Transformers/ActionlogsTransformer.php | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 30468c85e..19d299a83 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -3,6 +3,7 @@ namespace App\Http\Transformers; use App\Helpers\Helper; use App\Models\Actionlog; +use App\Models\CustomField; use App\Models\Setting; use App\Models\Company; use App\Models\Supplier; @@ -42,6 +43,7 @@ class ActionlogsTransformer public function transformActionlog (Actionlog $actionlog, $settings = null) { $icon = $actionlog->present()->icon(); + $custom_field = CustomField::all(); if ($actionlog->filename!='') { $icon = e(\App\Helpers\Helper::filetype_icon($actionlog->filename)); } @@ -52,16 +54,19 @@ class ActionlogsTransformer if ($meta_array) { foreach ($meta_array as $fieldname => $fieldata) { - if ((strlen($this->clean_field($fieldata->old)) == 200) || (strlen($this->clean_field($fieldata->new))== 200)) { - $clean_meta[$fieldname]['old'] = "encrypted"; - $clean_meta[$fieldname]['new'] = "encrypted"; - } else { + if( str_starts_with($fieldname, '_snipeit_')){ + + if( $custom_field->where('name', '=', $fieldname)->where('field_encrypted', true)){ + $clean_meta[$fieldname]['old'] = "encrypted"; + $clean_meta[$fieldname]['new'] = "encrypted"; + } + } + else { $clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old); $clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new); } } - \Log::info("Clean Meta is: " . print_r($clean_meta, true)); $clean_meta = $this->changedInfo($clean_meta); } } @@ -150,40 +155,43 @@ class ActionlogsTransformer * @return array */ public function changedInfo(array $clean_meta) - { + { $location = Location::all(); + $company = Company::all(); + $supplier = Supplier::all(); + $model = AssetModel::all(); + if(array_key_exists('rtd_location_id',$clean_meta)) { - $clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". Location::find($clean_meta['rtd_location_id']['old'])->name : trans('general.unassigned'); - $clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". Location::find($clean_meta['rtd_location_id']['new'])->name : trans('general.unassigned'); + $clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". $location->find($clean_meta['rtd_location_id']['old'])->name : trans('general.unassigned'); + $clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". $location->find($clean_meta['rtd_location_id']['new'])->name : trans('general.unassigned'); $clean_meta['Default Location'] = $clean_meta['rtd_location_id']; unset($clean_meta['rtd_location_id']); } if(array_key_exists('location_id', $clean_meta)) { - $clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".Location::find($clean_meta['location_id']['old'])->name : trans('general.unassigned'); - $clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".Location::find($clean_meta['location_id']['new'])->name : trans('general.unassigned'); + $clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".$location->find($clean_meta['location_id']['old'])->name : trans('general.unassigned'); + $clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".$location->find($clean_meta['location_id']['new'])->name : trans('general.unassigned'); $clean_meta['Current Location'] = $clean_meta['location_id']; unset($clean_meta['location_id']); } if(array_key_exists('model_id', $clean_meta)) { - $clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".AssetModel::find($clean_meta['model_id']['old'])->name; - $clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".AssetModel::find($clean_meta['model_id']['new'])->name; /* model is required at asset creation */ + $clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".$model->find($clean_meta['model_id']['old'])->name; + $clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".$model->find($clean_meta['model_id']['new'])->name; /* model is required at asset creation */ $clean_meta['Model'] = $clean_meta['model_id']; unset($clean_meta['model_id']); } if(array_key_exists('company_id', $clean_meta)) { - $clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."]".Company::find($clean_meta['company_id']['old'])->name : trans('general.unassigned'); - $clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ".Company::find($clean_meta['company_id']['new'])->name : trans('general.unassigned'); + $clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."]".$company->find($clean_meta['company_id']['old'])->name : trans('general.unassigned'); + $clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ".$company->find($clean_meta['company_id']['new'])->name : trans('general.unassigned'); $clean_meta['Company'] = $clean_meta['company_id']; unset($clean_meta['company_id']); } if(array_key_exists('supplier_id', $clean_meta)) { - $clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ".Supplier::find($clean_meta['supplier_id']['old'])->name : trans('general.unassigned'); - $clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ".Supplier::find($clean_meta['supplier_id']['new'])->name : trans('general.unassigned'); + $clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ".$supplier->find($clean_meta['supplier_id']['old'])->name : trans('general.unassigned'); + $clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ".$supplier->find($clean_meta['supplier_id']['new'])->name : trans('general.unassigned'); $clean_meta['Supplier'] = $clean_meta['supplier_id']; unset($clean_meta['supplier_id']); } if(array_key_exists('asset_eol_date', $clean_meta)) { - $clean_meta['EOL date'] = $clean_meta['asset_eol_date']; unset($clean_meta['asset_eol_date']); } From 1019287c760beee49139637837a11b12e9298505 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Aug 2023 12:36:43 -0700 Subject: [PATCH 03/14] retarget key --- app/Http/Transformers/ActionlogsTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 19d299a83..5d8d7e2d6 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -56,7 +56,7 @@ class ActionlogsTransformer foreach ($meta_array as $fieldname => $fieldata) { if( str_starts_with($fieldname, '_snipeit_')){ - if( $custom_field->where('name', '=', $fieldname)->where('field_encrypted', true)){ + if( $custom_field->where('db_column', '=', $fieldname)->where('field_encrypted', true)){ $clean_meta[$fieldname]['old'] = "encrypted"; $clean_meta[$fieldname]['new'] = "encrypted"; } From 92ddf8fc67f32cf628a5c8917829720ee63c3f5d Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Aug 2023 12:38:50 -0700 Subject: [PATCH 04/14] removed dead space --- app/Http/Transformers/ActionlogsTransformer.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 5d8d7e2d6..cb28ff811 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -55,7 +55,6 @@ class ActionlogsTransformer if ($meta_array) { foreach ($meta_array as $fieldname => $fieldata) { if( str_starts_with($fieldname, '_snipeit_')){ - if( $custom_field->where('db_column', '=', $fieldname)->where('field_encrypted', true)){ $clean_meta[$fieldname]['old'] = "encrypted"; $clean_meta[$fieldname]['new'] = "encrypted"; @@ -65,7 +64,6 @@ class ActionlogsTransformer $clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old); $clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new); } - } $clean_meta = $this->changedInfo($clean_meta); } @@ -132,7 +130,6 @@ class ActionlogsTransformer 'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'), ]; // \Log::info("Clean Meta is: ".print_r($clean_meta,true)); - //dd($array); return $array; } From ce60db009c51c41ce523b0818849528b4701e6a2 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Aug 2023 00:32:43 -0700 Subject: [PATCH 05/14] adds soft deletes to eager loading --- app/Http/Transformers/ActionlogsTransformer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index cb28ff811..e7ac55f52 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -152,10 +152,10 @@ class ActionlogsTransformer * @return array */ public function changedInfo(array $clean_meta) - { $location = Location::all(); - $company = Company::all(); - $supplier = Supplier::all(); - $model = AssetModel::all(); + { $location = Location::withTrashed()->all(); + $company = Company::withTrashed()->all(); + $supplier = Supplier::withTrashed()->all(); + $model = AssetModel::withTrashed()->get(); if(array_key_exists('rtd_location_id',$clean_meta)) { From 27488c1009c1a8f9d2156c414d7eb7b21ca14174 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Aug 2023 00:32:43 -0700 Subject: [PATCH 06/14] adds soft deletes to eager loading --- app/Http/Transformers/ActionlogsTransformer.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index cb28ff811..dcccc92e6 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -152,10 +152,10 @@ class ActionlogsTransformer * @return array */ public function changedInfo(array $clean_meta) - { $location = Location::all(); - $company = Company::all(); - $supplier = Supplier::all(); - $model = AssetModel::all(); + { $location = Location::withTrashed()->get(); + $company = Company::withTrashed()->get(); + $supplier = Supplier::withTrashed()->get(); + $model = AssetModel::withTrashed()->get(); if(array_key_exists('rtd_location_id',$clean_meta)) { From 0fc79ec936537b03fd81049b3a955a3d963715da Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Aug 2023 00:40:59 -0700 Subject: [PATCH 07/14] fixes conflicts --- app/Http/Transformers/ActionlogsTransformer.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index e7ac55f52..99dd0c47e 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -151,10 +151,11 @@ class ActionlogsTransformer * @param array $clean_meta * @return array */ - public function changedInfo(array $clean_meta) - { $location = Location::withTrashed()->all(); - $company = Company::withTrashed()->all(); - $supplier = Supplier::withTrashed()->all(); + public function changedInfo(array $clean_meta) { + + $location = Location::withTrashed()->get(); + $company = Company::withTrashed()->get(); + $supplier = Supplier::withTrashed()->get(); $model = AssetModel::withTrashed()->get(); From 74f45a44739c96d5c6776efa6238fdf64860e3ba Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Mon, 28 Aug 2023 19:35:46 -0700 Subject: [PATCH 08/14] reworks company queries for asset history --- app/Http/Transformers/ActionlogsTransformer.php | 11 ++++++++--- resources/lang/en/admin/companies/message.php | 1 + 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index 9198f89d0..16f413c7e 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -153,7 +153,6 @@ class ActionlogsTransformer */ public function changedInfo(array $clean_meta) { $location = Location::withTrashed()->get(); - $company = Company::withTrashed()->get(); $supplier = Supplier::withTrashed()->get(); $model = AssetModel::withTrashed()->get(); @@ -179,8 +178,14 @@ class ActionlogsTransformer unset($clean_meta['model_id']); } if(array_key_exists('company_id', $clean_meta)) { - $clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."]".$company->find($clean_meta['company_id']['old'])->name : trans('general.unassigned'); - $clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ".$company->find($clean_meta['company_id']['new'])->name : trans('general.unassigned'); + $oldCompany = Company::find($clean_meta['company_id']['old']); + $oldCompanyName = $oldCompany->name ?? trans('admin/companies/message.deleted'); + + $newCompany = Company::find($clean_meta['company_id']['new']); + $newCompanyName = $newCompany->name ?? trans('admin/companies/message.deleted'); + + $clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."] ". $oldCompanyName : trans('general.unassigned'); + $clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ". $newCompanyName : trans('general.unassigned'); $clean_meta['Company'] = $clean_meta['company_id']; unset($clean_meta['company_id']); } diff --git a/resources/lang/en/admin/companies/message.php b/resources/lang/en/admin/companies/message.php index b44bdd4b8..e440b7ac5 100644 --- a/resources/lang/en/admin/companies/message.php +++ b/resources/lang/en/admin/companies/message.php @@ -2,6 +2,7 @@ return [ 'does_not_exist' => 'Company does not exist.', + 'deleted' => 'Deleted company', 'assoc_users' => 'This company is currently associated with at least one model and cannot be deleted. Please update your models to no longer reference this company and try again. ', 'create' => [ 'error' => 'Company was not created, please try again.', From 2a93c388306bdbd665cf950f6de79fa657c89deb Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 30 Aug 2023 16:40:28 +0100 Subject: [PATCH 09/14] =?UTF-8?q?Don=E2=80=99t=20cast=20as=20boolean,=20va?= =?UTF-8?q?lidate=20as=20boolean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: snipe --- app/Models/User.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Models/User.php b/app/Models/User.php index 0d49b977c..f54d99188 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -69,15 +69,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo ]; protected $casts = [ - 'activated' => 'boolean', 'manager_id' => 'integer', 'location_id' => 'integer', 'company_id' => 'integer', - 'vip' => 'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'deleted_at' => 'datetime', - 'autoassign_licenses' => 'boolean', ]; /** @@ -103,6 +100,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo 'state' => 'min:2|max:191|nullable', 'country' => 'min:2|max:191|nullable', 'zip' => 'max:10|nullable', + 'vip' => 'boolean', + 'remote' => 'boolean', + 'activated' => 'boolean', ]; /** From 07c3fe1fcedcd159eafb452075eeeeb6c55cfb04 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 30 Aug 2023 09:42:53 -0700 Subject: [PATCH 10/14] Update assertions to account for type change --- tests/Feature/Users/UpdateUserTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Users/UpdateUserTest.php b/tests/Feature/Users/UpdateUserTest.php index 9ddb32362..0066788f0 100644 --- a/tests/Feature/Users/UpdateUserTest.php +++ b/tests/Feature/Users/UpdateUserTest.php @@ -22,7 +22,7 @@ class UpdateUserTest extends TestCase 'activated' => 1, ]); - $this->assertTrue($user->refresh()->activated); + $this->assertEquals(1, $user->refresh()->activated); } public function testUsersCanBeDeactivated() @@ -39,7 +39,7 @@ class UpdateUserTest extends TestCase // 'activated' => 0, ]); - $this->assertFalse($user->refresh()->activated); + $this->assertEquals(0, $user->refresh()->activated); } public function testUsersUpdatingThemselvesDoNotDeactivateTheirAccount() @@ -56,6 +56,6 @@ class UpdateUserTest extends TestCase // 'activated' => 0, ]); - $this->assertTrue($admin->refresh()->activated); + $this->assertEquals(1, $admin->refresh()->activated); } } From fb455be40631ce73ebd6b61b71a1b9e33e3b9f3f Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 30 Aug 2023 19:13:38 +0100 Subject: [PATCH 11/14] Added tests Signed-off-by: snipe --- tests/Feature/Api/Users/UpdateUserApiTest.php | 68 +++++++++++++++++++ tests/Feature/Users/UpdateUserTest.php | 44 +++++++++--- 2 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 tests/Feature/Api/Users/UpdateUserApiTest.php diff --git a/tests/Feature/Api/Users/UpdateUserApiTest.php b/tests/Feature/Api/Users/UpdateUserApiTest.php new file mode 100644 index 000000000..81c115464 --- /dev/null +++ b/tests/Feature/Api/Users/UpdateUserApiTest.php @@ -0,0 +1,68 @@ +superuser()->create(); + $user = User::factory()->create(['activated' => 0]); + + $this->actingAsForApi($admin) + ->patch(route('api.users.update', $user), [ + 'activated' => 1, + ]); + + $this->assertEquals(1, $user->refresh()->activated); + } + + public function testApiUsersCanBeActivatedWithBooleanTrue() + { + $admin = User::factory()->superuser()->create(); + $user = User::factory()->create(['activated' => false]); + + $this->actingAsForApi($admin) + ->patch(route('api.users.update', $user), [ + 'activated' => true, + ]); + + $this->assertEquals(1, $user->refresh()->activated); + } + + public function testApiUsersCanBeDeactivatedWithNumber() + { + $admin = User::factory()->superuser()->create(); + $user = User::factory()->create(['activated' => true]); + + $this->actingAsForApi($admin) + ->patch(route('api.users.update', $user), [ + 'activated' => 0, + ]); + + $this->assertEquals(0, $user->refresh()->activated); + } + + public function testApiUsersCanBeDeactivatedWithBooleanFalse() + { + $admin = User::factory()->superuser()->create(); + $user = User::factory()->create(['activated' => true]); + + $this->actingAsForApi($admin) + ->patch(route('api.users.update', $user), [ + 'activated' => false, + ]); + + $this->assertEquals(0, $user->refresh()->activated); + } + +} diff --git a/tests/Feature/Users/UpdateUserTest.php b/tests/Feature/Users/UpdateUserTest.php index 0066788f0..92245059e 100644 --- a/tests/Feature/Users/UpdateUserTest.php +++ b/tests/Feature/Users/UpdateUserTest.php @@ -10,10 +10,10 @@ class UpdateUserTest extends TestCase { use InteractsWithSettings; - public function testUsersCanBeActivated() + public function testUsersCanBeActivatedWithNumber() { $admin = User::factory()->superuser()->create(); - $user = User::factory()->create(['activated' => false]); + $user = User::factory()->create(['activated' => 0]); $this->actingAs($admin) ->put(route('users.update', $user), [ @@ -25,7 +25,22 @@ class UpdateUserTest extends TestCase $this->assertEquals(1, $user->refresh()->activated); } - public function testUsersCanBeDeactivated() + public function testUsersCanBeActivatedWithBooleanTrue() + { + $admin = User::factory()->superuser()->create(); + $user = User::factory()->create(['activated' => false]); + + $this->actingAs($admin) + ->put(route('users.update', $user), [ + 'first_name' => $user->first_name, + 'username' => $user->username, + 'activated' => true, + ]); + + $this->assertEquals(1, $user->refresh()->activated); + } + + public function testUsersCanBeDeactivatedWithNumber() { $admin = User::factory()->superuser()->create(); $user = User::factory()->create(['activated' => true]); @@ -34,9 +49,22 @@ class UpdateUserTest extends TestCase ->put(route('users.update', $user), [ 'first_name' => $user->first_name, 'username' => $user->username, - // checkboxes that are not checked are - // not included in the request payload - // 'activated' => 0, + 'activated' => 0, + ]); + + $this->assertEquals(0, $user->refresh()->activated); + } + + public function testUsersCanBeDeactivatedWithBooleanFalse() + { + $admin = User::factory()->superuser()->create(); + $user = User::factory()->create(['activated' => true]); + + $this->actingAs($admin) + ->put(route('users.update', $user), [ + 'first_name' => $user->first_name, + 'username' => $user->username, + 'activated' => false, ]); $this->assertEquals(0, $user->refresh()->activated); @@ -50,10 +78,6 @@ class UpdateUserTest extends TestCase ->put(route('users.update', $admin), [ 'first_name' => $admin->first_name, 'username' => $admin->username, - // checkboxes that are disabled are not - // included in the request payload - // even if they are checked - // 'activated' => 0, ]); $this->assertEquals(1, $admin->refresh()->activated); From 663faffcc1f6cbc7fe9f46e99a2d61b59f036d74 Mon Sep 17 00:00:00 2001 From: snipe Date: Wed, 30 Aug 2023 19:13:55 +0100 Subject: [PATCH 12/14] Un-cast byod, validate as boolean Signed-off-by: snipe --- app/Models/Asset.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 6792cf285..d95aec51c 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -82,7 +82,6 @@ class Asset extends Depreciable 'location_id' => 'integer', 'rtd_company_id' => 'integer', 'supplier_id' => 'integer', - 'byod' => 'boolean', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'deleted_at' => 'datetime', @@ -105,6 +104,7 @@ class Asset extends Depreciable 'purchase_cost' => 'numeric|nullable|gte:0', 'supplier_id' => 'exists:suppliers,id|nullable', 'asset_eol_date' => 'date|max:10|min:10|nullable', + 'byod' => 'boolean', ]; /** From 5828d2995208bc9d1224fe5730ba20a8789f5589 Mon Sep 17 00:00:00 2001 From: Marcus Moore Date: Wed, 30 Aug 2023 16:43:18 -0700 Subject: [PATCH 13/14] Remove Dusk --- .chipperci.yml | 17 ---- .gitignore | 2 - TESTING.md | 31 ------ app/Providers/AppServiceProvider.php | 7 +- composer.json | 2 - composer.lock | 140 +-------------------------- tests/Browser/LoginTest.php | 46 --------- tests/Browser/Pages/HomePage.php | 41 -------- tests/Browser/Pages/Page.php | 20 ---- tests/Browser/console/.gitignore | 2 - tests/Browser/screenshots/.gitignore | 2 - tests/Browser/source/.gitignore | 2 - tests/DuskTestCase.php | 70 -------------- 13 files changed, 2 insertions(+), 380 deletions(-) delete mode 100644 tests/Browser/LoginTest.php delete mode 100644 tests/Browser/Pages/HomePage.php delete mode 100644 tests/Browser/Pages/Page.php delete mode 100644 tests/Browser/console/.gitignore delete mode 100644 tests/Browser/screenshots/.gitignore delete mode 100644 tests/Browser/source/.gitignore delete mode 100644 tests/DuskTestCase.php diff --git a/.chipperci.yml b/.chipperci.yml index 0c18b253c..bfd1e9ecb 100644 --- a/.chipperci.yml +++ b/.chipperci.yml @@ -6,7 +6,6 @@ environment: services: - mysql: 5.7 - - dusk: on: push: @@ -43,19 +42,3 @@ pipeline: - name: PHPUnit Feature Tests cmd: | php artisan test --testsuite Feature - -# - name: Browser Tests -# cmd: | -# cp -v .env.dusk.example .env.dusk.ci -# sed -i "s@APP_ENV=.*@APP_ENV=ci@g" .env.dusk.ci -# sed -i "s@APP_URL=.*@APP_URL=http://$BUILD_HOST:8000@g" .env.dusk.ci -# #sed -i "s@DB_HOST=.*@DB_HOST=mysql@g" .env.dusk.ci -# sed -i "s@DB_HOST=.*@DB_HOST=$DB_HOST@g" .env.dusk.ci -# sed -i "s@DB_USERNAME=.*@DB_USERNAME=chipperci@g" .env.dusk.ci -# sed -i "s@DB_DATABASE=.*@DB_DATABASE=chipperci@g" .env.dusk.ci -# sed -i "s@DB_PASSWORD=.*@DB_PASSWORD=secret@g" .env.dusk.ci -# -# php -S [::0]:8000 -t public 2>server.log & -# sleep 2 -# php artisan dusk:chrome-driver $CHROME_DRIVER -# php artisan dusk --env=ci diff --git a/.gitignore b/.gitignore index f0e9bfcec..bf8360ba2 100755 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ .couscous .DS_Store .env -.env.dusk.* -!.env.dusk.example .env.testing phpstan.neon .idea diff --git a/TESTING.md b/TESTING.md index 3f0e58810..d1e062541 100644 --- a/TESTING.md +++ b/TESTING.md @@ -18,34 +18,3 @@ Now you are ready to run the entire test suite from your terminal: To run individual test files, you can pass the path to the test that you want to run: `php artisan test tests/Unit/AccessoryTest.php` - -## Browser Tests - -Browser tests are run via [Laravel Dusk](https://laravel.com/docs/8.x/dusk) and require Google Chrome to be installed. - -Before attempting to run Dusk tests copy the example environment file for Dusk and update the values to match your environment: - -`cp .env.dusk.example .env.dusk.local` -> `local` refers to the value of `APP_ENV` in your `.env` so if you have it set to `dev` then the file should be named `.env.dusk.dev`. - -**Important**: Dusk tests cannot be run using an in-memory SQLite database. Additionally, the Dusk test suite uses the `DatabaseMigrations` trait which will leave the database in a fresh state after running. Therefore, it is recommended that you create a test database and point `DB_DATABASE` in `.env.dusk.local` to it. - -### Running Browser Tests - -Your application needs to be configured and up and running in order for the browser tests to actually run. When running the tests locally, you can start the application using the following command: - -`php artisan serve` - -Now you are ready to run the test suite. Use the following command from another terminal tab or window: - -`php artisan dusk` - -To run individual test files, you can pass the path to the test that you want to run: - -`php artisan dusk tests/Browser/LoginTest.php` - -If you get an error when attempting to run Dusk tests that says `Couldn't connect to server` run: - -`php artisan dusk:chrome-driver --detect` - -This command will install the specific ChromeDriver Dusk needs for your operating system and Chrome version. diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 607d206a6..325fb8ad1 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -75,12 +75,7 @@ class AppServiceProvider extends ServiceProvider // Only load rollbar if there is a rollbar key and the app is in production if (($this->app->environment('production')) && (config('logging.channels.rollbar.access_token'))) { $this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class); - } - - // Only load dusk's service provider if the app is in local or develop mode - if ($this->app->environment(['local', 'develop'])) { - $this->app->register(\Laravel\Dusk\DuskServiceProvider::class); - } + } $this->app->singleton('ArieTimmerman\Laravel\SCIMServer\SCIMConfig', SnipeSCIMConfig::class); // this overrides the default SCIM configuration with our own diff --git a/composer.json b/composer.json index 20d76a1d9..020b2f9ca 100644 --- a/composer.json +++ b/composer.json @@ -77,7 +77,6 @@ "require-dev": { "brianium/paratest": "^6.6", "fakerphp/faker": "^1.16", - "laravel/dusk": "^6.25", "mockery/mockery": "^1.4", "nunomaduro/larastan": "^1.0", "nunomaduro/phpinsights": "^2.7", @@ -107,7 +106,6 @@ }, "autoload-dev": { "classmap": [ - "tests/DuskTestCase.php", "tests/TestCase.php" ], "psr-4": { diff --git a/composer.lock b/composer.lock index 54d3e556b..9f84ec8b2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f30d1bebf56af36eb55a56d093b54650", + "content-hash": "348f96db24a0f8dfb595ee38b38b34eb", "packages": [ { "name": "alek13/slack", @@ -13521,79 +13521,6 @@ }, "time": "2022-04-13T08:02:27+00:00" }, - { - "name": "laravel/dusk", - "version": "v6.25.2", - "source": { - "type": "git", - "url": "https://github.com/laravel/dusk.git", - "reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/dusk/zipball/25a595ac3dc82089a91af10dd23b0d58fd3f6d0b", - "reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-zip": "*", - "illuminate/console": "^6.0|^7.0|^8.0|^9.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0", - "nesbot/carbon": "^2.0", - "php": "^7.2|^8.0", - "php-webdriver/webdriver": "^1.9.0", - "symfony/console": "^4.3|^5.0|^6.0", - "symfony/finder": "^4.3|^5.0|^6.0", - "symfony/process": "^4.3|^5.0|^6.0", - "vlucas/phpdotenv": "^3.0|^4.0|^5.2" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "orchestra/testbench": "^4.16|^5.17.1|^6.12.1|^7.0", - "phpunit/phpunit": "^7.5.15|^8.4|^9.0" - }, - "suggest": { - "ext-pcntl": "Used to gracefully terminate Dusk when tests are running." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.x-dev" - }, - "laravel": { - "providers": [ - "Laravel\\Dusk\\DuskServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Dusk\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Laravel Dusk provides simple end-to-end testing and browser automation.", - "keywords": [ - "laravel", - "testing", - "webdriver" - ], - "support": { - "issues": "https://github.com/laravel/dusk/issues", - "source": "https://github.com/laravel/dusk/tree/v6.25.2" - }, - "time": "2022-09-29T09:37:07+00:00" - }, { "name": "league/container", "version": "4.2.0", @@ -14230,71 +14157,6 @@ }, "time": "2022-02-21T12:50:22+00:00" }, - { - "name": "php-webdriver/webdriver", - "version": "1.12.1", - "source": { - "type": "git", - "url": "https://github.com/php-webdriver/php-webdriver.git", - "reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a", - "reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-zip": "*", - "php": "^5.6 || ~7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.12", - "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0" - }, - "replace": { - "facebook/webdriver": "*" - }, - "require-dev": { - "ondram/ci-detector": "^2.1 || ^3.5 || ^4.0", - "php-coveralls/php-coveralls": "^2.4", - "php-mock/php-mock-phpunit": "^1.1 || ^2.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9", - "squizlabs/php_codesniffer": "^3.5", - "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0" - }, - "suggest": { - "ext-SimpleXML": "For Firefox profile creation" - }, - "type": "library", - "autoload": { - "files": [ - "lib/Exception/TimeoutException.php" - ], - "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", - "homepage": "https://github.com/php-webdriver/php-webdriver", - "keywords": [ - "Chromedriver", - "geckodriver", - "php", - "selenium", - "webdriver" - ], - "support": { - "issues": "https://github.com/php-webdriver/php-webdriver/issues", - "source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1" - }, - "time": "2022-05-03T12:16:34+00:00" - }, { "name": "phpstan/phpdoc-parser", "version": "1.22.1", diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php deleted file mode 100644 index 18f5172f1..000000000 --- a/tests/Browser/LoginTest.php +++ /dev/null @@ -1,46 +0,0 @@ -make(); - - // We override the existing password to use a hash of one we know - $user->password = '$2y$10$8o5W8fgAKJbN3Kz4taepeeRVgKsG8pkZ1L4eJfdEKrn2mgI/JgCJy'; - - // We want a user that is a superuser - $user->permissions = '{"superuser": 1}'; - - $user->save(); - - Setting::factory()->create(); - - $this->browse(function (Browser $browser) { - $browser->visitRoute('login') - ->assertSee(trans('auth/general.login_prompt')); - }); - - $this->browse(function ($browser) use ($user) { - $browser->visitRoute('login') - ->type('username', $user->username) - ->type('password', 'password') - ->press(trans('auth/general.login')) - ->assertPathIs('/'); - $browser->screenshot('dashboard'); - }); - } -} diff --git a/tests/Browser/Pages/HomePage.php b/tests/Browser/Pages/HomePage.php deleted file mode 100644 index 26bf174f3..000000000 --- a/tests/Browser/Pages/HomePage.php +++ /dev/null @@ -1,41 +0,0 @@ - '#selector', - ]; - } -} diff --git a/tests/Browser/Pages/Page.php b/tests/Browser/Pages/Page.php deleted file mode 100644 index f8d76222c..000000000 --- a/tests/Browser/Pages/Page.php +++ /dev/null @@ -1,20 +0,0 @@ - '#selector', - ]; - } -} diff --git a/tests/Browser/console/.gitignore b/tests/Browser/console/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/tests/Browser/console/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/tests/Browser/screenshots/.gitignore b/tests/Browser/screenshots/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/tests/Browser/screenshots/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/tests/Browser/source/.gitignore b/tests/Browser/source/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/tests/Browser/source/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php deleted file mode 100644 index af46d0e3d..000000000 --- a/tests/DuskTestCase.php +++ /dev/null @@ -1,70 +0,0 @@ -addArguments(collect([ - '--window-size=1920,1080', - ])->unless($this->hasHeadlessDisabled(), function ($items) { - return $items->merge([ - '--disable-gpu', - '--headless', - ]); - })->all()); - - return RemoteWebDriver::create( - $_ENV['DUSK_DRIVER_URL'] ?? 'http://127.0.0.1:9515', - DesiredCapabilities::chrome()->setCapability( - ChromeOptions::CAPABILITY, $options - ) - ); - } - - /** - * Determine whether the Dusk command has disabled headless mode. - * - * @return bool - */ - protected function hasHeadlessDisabled() - { - return isset($_SERVER['DUSK_HEADLESS_DISABLED']) || - isset($_ENV['DUSK_HEADLESS_DISABLED']); - } -} From 83b178f5b2a9955cc56f31525246182f047c04c5 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 31 Aug 2023 18:03:32 +0100 Subject: [PATCH 14/14] Added model name and number to dynamic url Signed-off-by: snipe --- app/Presenters/AssetPresenter.php | 6 ++++-- resources/lang/en/admin/manufacturers/message.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Presenters/AssetPresenter.php b/app/Presenters/AssetPresenter.php index ec5093358..4a068ba64 100644 --- a/app/Presenters/AssetPresenter.php +++ b/app/Presenters/AssetPresenter.php @@ -548,8 +548,10 @@ class AssetPresenter extends Presenter public function dynamicWarrantyUrl() { $warranty_lookup_url = $this->model->model->manufacturer->warranty_lookup_url; - $url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale,$warranty_lookup_url)); - $url = (str_replace('{SERIAL}',$this->model->serial,$url)); + $url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale, $warranty_lookup_url)); + $url = (str_replace('{SERIAL}', urlencode($this->model->serial), $url)); + $url = (str_replace('{MODEL_NAME}', urlencode($this->model->model->name), $url)); + $url = (str_replace('{MODEL_NUMBER}', urlencode($this->model->model->model_number), $url)); return $url; } diff --git a/resources/lang/en/admin/manufacturers/message.php b/resources/lang/en/admin/manufacturers/message.php index d6656683a..877635849 100644 --- a/resources/lang/en/admin/manufacturers/message.php +++ b/resources/lang/en/admin/manufacturers/message.php @@ -2,7 +2,7 @@ return array( - 'support_url_help' => 'Use {LOCALE} and {SERIAL} in your URL as variables to have those values auto-populate when viewing assets.', + 'support_url_help' => 'Variables {LOCALE}, {SERIAL}, {MODEL_NUMBER}, and {MODEL_NAME} may be used in your URL to have those values auto-populate when viewing assets - for example https://support.apple.com/{LOCALE}/{SERIAL}.', 'does_not_exist' => 'Manufacturer does not exist.', 'assoc_users' => 'This manufacturer is currently associated with at least one model and cannot be deleted. Please update your models to no longer reference this manufacturer and try again. ',