diff --git a/database/factories/AssetFactory.php b/database/factories/AssetFactory.php index 174debb9cd..0916fea17d 100644 --- a/database/factories/AssetFactory.php +++ b/database/factories/AssetFactory.php @@ -4,6 +4,7 @@ namespace Database\Factories; use App\Models\Asset; use App\Models\AssetModel; +use App\Models\CustomField; use App\Models\Location; use App\Models\Statuslabel; use App\Models\Supplier; @@ -353,9 +354,15 @@ class AssetFactory extends Factory return $this->state(['requestable' => false]); } - public function hasEncryptedCustomField() + public function hasEncryptedCustomField(CustomField $field = null) { - return $this->state(['model_id' => AssetModel::where('name', 'asset with encrypted field')->first() ?? AssetModel::factory()->withEncryptedField()]); + // @todo: update this so existing asset model is used if present on the asset + // (may have been created in a test case) + return $this->state(function () use ($field) { + return [ + 'model_id' => AssetModel::factory()->hasEncryptedCustomField($field), + ]; + }); } diff --git a/database/factories/AssetModelFactory.php b/database/factories/AssetModelFactory.php index f7e33d4939..ed3d478261 100644 --- a/database/factories/AssetModelFactory.php +++ b/database/factories/AssetModelFactory.php @@ -431,28 +431,12 @@ class AssetModelFactory extends Factory }); } - public function withEncryptedField() + public function hasEncryptedCustomField(CustomField $field = null) { - return $this->state(function () { - $field = CustomField::factory()->testEncrypted()->create(); // TODO - having to create and then 'find' the thing you just created is WEIRD + return $this->state(function () use ($field) { return [ - 'name' => 'asset with encrypted field', - 'category_id' => function () { - return Category::where('name', 'Mobile Phones')->first() ?? Category::factory()->assetMobileCategory(); - }, - 'manufacturer_id' => function () { - return Manufacturer::where('name', 'Apple')->first() ?? Manufacturer::factory()->apple(); - }, - 'eol' => '12', - 'depreciation_id' => function () { - return Depreciation::where('name', 'Computer Depreciation')->first() ?? Depreciation::factory()->computer(); - }, - 'image' => 'iphone12.jpeg', - 'fieldset_id' => function () use ($field) { - return CustomFieldset::where('name', 'Has Encrypted Custom Field')->first() ?? CustomFieldset::factory()->has_encrypted_custom_field()->hasAttached(CustomField::where('name', 'Test Encrypted')->first(), ['order' => 1, 'required' => 0], 'fields'); - }, + 'fieldset_id' => CustomFieldset::factory()->hasEncryptedCustomField($field), ]; }); } - } diff --git a/database/factories/CustomFieldsetFactory.php b/database/factories/CustomFieldsetFactory.php index f0ace3f539..9a410ba25f 100644 --- a/database/factories/CustomFieldsetFactory.php +++ b/database/factories/CustomFieldsetFactory.php @@ -45,12 +45,12 @@ class CustomFieldsetFactory extends Factory }); } - public function has_encrypted_custom_field() + public function hasEncryptedCustomField(CustomField $field = null) { - return $this->state(function () { - return [ - 'name' => 'Has Encrypted Custom Field', - ]; + return $this->afterCreating(function (CustomFieldset $fieldset) use ($field) { + $field = $field ?? CustomField::factory()->testEncrypted()->create(); + + $fieldset->fields()->attach($field, ['order' => '1', 'required' => false]); }); } } diff --git a/tests/Feature/Api/Assets/AssetStoreTest.php b/tests/Feature/Api/Assets/AssetStoreTest.php index 02478640cb..aee110976d 100644 --- a/tests/Feature/Api/Assets/AssetStoreTest.php +++ b/tests/Feature/Api/Assets/AssetStoreTest.php @@ -6,11 +6,11 @@ use App\Models\Asset; use App\Models\AssetModel; use App\Models\Company; use App\Models\CustomField; -use App\Models\CustomFieldset; use App\Models\Location; use App\Models\Statuslabel; use App\Models\Supplier; use App\Models\User; +use Illuminate\Support\Facades\Crypt; use Illuminate\Testing\Fluent\AssertableJson; use Tests\TestCase; @@ -482,35 +482,52 @@ class AssetStoreTest extends TestCase }); } - public function testEncryptedCustomField() + public function testEncryptedCustomFieldCanBeStored() { + $status = Statuslabel::factory()->create(); $field = CustomField::factory()->testEncrypted()->create(); - $asset = Asset::factory()->hasEncryptedCustomField()->create(); $superuser = User::factory()->superuser()->create(); - $normal_user = User::factory()->editAssets()->create(); + $assetData = Asset::factory()->hasEncryptedCustomField($field)->make(); - //first, test that an Admin user can save the encrypted custom field $response = $this->actingAsForApi($superuser) - ->patchJson(route('api.assets.update', $asset->id), [ - $field->db_column_name() => 'This is encrypted field' + ->postJson(route('api.assets.store'), [ + $field->db_column_name() => 'This is encrypted field', + 'model_id' => $assetData->model->id, + 'status_id' => $status->id, + 'asset_tag' => '1234', ]) ->assertStatusMessageIs('success') ->assertOk() ->json(); - $asset->refresh(); - $this->assertEquals(\Crypt::decrypt($asset->{$field->db_column_name()}), 'This is encrypted field'); - //next, test that a 'normal' user *cannot* change the encrypted custom field + $asset = Asset::findOrFail($response['payload']['id']); + $this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()})); + } + + public function testPermissionNeededToStoreEncryptedField() + { + // @todo: + $this->markTestIncomplete(); + + $status = Statuslabel::factory()->create(); + $field = CustomField::factory()->testEncrypted()->create(); + $normal_user = User::factory()->editAssets()->create(); + $assetData = Asset::factory()->hasEncryptedCustomField($field)->make(); + $response = $this->actingAsForApi($normal_user) - ->patchJson(route('api.assets.update', $asset->id), [ - $field->db_column_name() => 'Some Other Value Entirely!' + ->postJson(route('api.assets.store'), [ + $field->db_column_name() => 'Some Other Value Entirely!', + 'model_id' => $assetData->model->id, + 'status_id' => $status->id, + 'asset_tag' => '1234', ]) + // @todo: this is 403 unauthorized ->assertStatusMessageIs('success') ->assertOk() ->assertMessagesAre('Asset updated successfully, but encrypted custom fields were not due to permissions') ->json(); - $asset->refresh(); - $this->assertEquals(\Crypt::decrypt($asset->{$field->db_column_name()}), 'This is encrypted field'); + $asset = Asset::findOrFail($response['payload']['id']); + $this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()})); } } diff --git a/tests/Feature/Api/Assets/AssetUpdateTest.php b/tests/Feature/Api/Assets/AssetUpdateTest.php index 758417fb41..f416645a8a 100644 --- a/tests/Feature/Api/Assets/AssetUpdateTest.php +++ b/tests/Feature/Api/Assets/AssetUpdateTest.php @@ -3,15 +3,9 @@ namespace Tests\Feature\Api\Assets; use App\Models\Asset; -use App\Models\AssetModel; -use App\Models\Company; use App\Models\CustomField; -use App\Models\CustomFieldset; -use App\Models\Location; -use App\Models\Statuslabel; -use App\Models\Supplier; use App\Models\User; -use Illuminate\Testing\Fluent\AssertableJson; +use Illuminate\Support\Facades\Crypt; use Tests\TestCase; class AssetUpdateTest extends TestCase @@ -19,41 +13,39 @@ class AssetUpdateTest extends TestCase public function testEncryptedCustomFieldCanBeUpdated() { $field = CustomField::factory()->testEncrypted()->create(); - $asset = Asset::factory()->hasEncryptedCustomField()->create(); + $asset = Asset::factory()->hasEncryptedCustomField($field)->create(); $superuser = User::factory()->superuser()->create(); - //first, test that an Admin user can save the encrypted custom field - $response = $this->actingAsForApi($superuser) + $this->actingAsForApi($superuser) ->patchJson(route('api.assets.update', $asset->id), [ $field->db_column_name() => 'This is encrypted field' ]) ->assertStatusMessageIs('success') - ->assertOk() - ->json(); + ->assertOk(); + $asset->refresh(); - $this->assertEquals(\Crypt::decrypt($asset->{$field->db_column_name()}), 'This is encrypted field'); + $this->assertEquals('This is encrypted field', Crypt::decrypt($asset->{$field->db_column_name()})); } public function testPermissionNeededToUpdateEncryptedField() { $field = CustomField::factory()->testEncrypted()->create(); - $asset = Asset::factory()->hasEncryptedCustomField()->create(); + $asset = Asset::factory()->hasEncryptedCustomField($field)->create(); $normal_user = User::factory()->editAssets()->create(); - $asset->{$field->db_column_name()} = \Crypt::encrypt("encrypted value should not change"); - $asset->save(); //is this needed? + $asset->{$field->db_column_name()} = Crypt::encrypt("encrypted value should not change"); + $asset->save(); - //test that a 'normal' user *cannot* change the encrypted custom field - $response = $this->actingAsForApi($normal_user) + // test that a 'normal' user *cannot* change the encrypted custom field + $this->actingAsForApi($normal_user) ->patchJson(route('api.assets.update', $asset->id), [ $field->db_column_name() => 'Some Other Value Entirely!' ]) ->assertStatusMessageIs('success') ->assertOk() - ->assertMessagesAre('Asset updated successfully, but encrypted custom fields were not due to permissions') - ->json(); - $asset->refresh(); - $this->assertEquals(\Crypt::decrypt($asset->{$field->db_column_name()}), "encrypted value should not change"); + ->assertMessagesAre('Asset updated successfully, but encrypted custom fields were not due to permissions'); + $asset->refresh(); + $this->assertEquals("encrypted value should not change", Crypt::decrypt($asset->{$field->db_column_name()})); } }