diff --git a/app/Models/License.php b/app/Models/License.php index 0997c1e57b..6e412f2fd7 100755 --- a/app/Models/License.php +++ b/app/Models/License.php @@ -43,7 +43,7 @@ class License extends Depreciable protected $rules = [ 'name' => 'required|string|min:3|max:255', - 'seats' => 'required|min:1|integer', + 'seats' => 'required|min:1|integer|limit_change:10000', // limit_change is a "pseudo-rule" that translates into 'between', see prepareLimitChangeRule() below 'license_email' => 'email|nullable|max:120', 'license_name' => 'string|nullable|max:100', 'notes' => 'string|nullable', @@ -148,6 +148,14 @@ class License extends Depreciable }); } + public function prepareLimitChangeRule($parameters, $field) + { + $actual_seat_count = $this->licenseseats()->count(); //we use the *actual* seat count here, in case your license has gone wonky + $lower_bound = $actual_seat_count - $parameters[0]; + $upper_bound = $actual_seat_count + $parameters[0]; + return ["between", ($lower_bound <= 0 ? 1 : $lower_bound), $upper_bound]; + } + /** * Balance seat counts * @@ -164,21 +172,17 @@ class License extends Depreciable // On Create, we just make one for each of the seats. $change = abs($oldSeats - $newSeats); if ($oldSeats > $newSeats) { - $license->load('licenseseats.user'); // Need to delete seats... lets see if if we have enough. - $seatsAvailableForDelete = $license->licenseseats->reject(function ($seat) { - return ((bool) $seat->assigned_to) || ((bool) $seat->asset_id); - }); + $seatsAvailableForDelete = $license->licenseseats()->whereNull('assigned_to')->whereNull('asset_id')->limit($change); if ($change > $seatsAvailableForDelete->count()) { Session::flash('error', trans('admin/licenses/message.assoc_users')); return false; } - for ($i = 1; $i <= $change; $i++) { - $seatsAvailableForDelete->pop()->delete(); - } + $seatsAvailableForDelete->delete(); + // Log Deletion of seats. $logAction = new Actionlog; $logAction->item_type = self::class; diff --git a/tests/Feature/Licenses/Ui/CreateLicenseTest.php b/tests/Feature/Licenses/Ui/CreateLicenseTest.php index 33f825bf95..535f0b3dba 100644 --- a/tests/Feature/Licenses/Ui/CreateLicenseTest.php +++ b/tests/Feature/Licenses/Ui/CreateLicenseTest.php @@ -2,7 +2,6 @@ namespace Tests\Feature\Licenses\Ui; -use App\Models\AssetModel; use App\Models\Category; use App\Models\License; use App\Models\Depreciation; @@ -41,7 +40,48 @@ class CreateLicenseTest extends TestCase $response->assertInvalid(['purchase_date']); $response->assertSessionHasErrors(['purchase_date']); $this->followRedirects($response)->assertSee(trans('general.error')); - $this->assertFalse(AssetModel::where('name', 'Test Invalid License')->exists()); + $this->assertFalse(License::where('name', 'Test Invalid License')->exists()); } + + public function testLicenseCreate() + { + $response = $this->actingAs(User::factory()->superuser()->create()) + ->from(route('licenses.create')) + ->post(route('licenses.store'), [ + 'name' => 'Test Valid License', + 'seats' => '10', + 'category_id' => Category::factory()->forLicenses()->create()->id, + ]); + $response->assertStatus(302); + $license = License::where('name', 'Test Valid License')->sole(); + $this->assertNotNull($license); + //$license->assetlog()->has_one_of_(); + $this->assertDatabaseHas('action_logs', ['action_type' => 'create', 'item_id' => $license->id, 'item_type' => License::class]); + $this->assertDatabaseHas('action_logs', ['action_type' => 'add seats', 'item_id' => $license->id, 'item_type' => License::class]); + $this->assertEquals($license->licenseseats()->count(), 10); + //test log entries? Sure. + + } + + public function testTooManySeatsLicenseCreate() + { + $response = $this->actingAs(User::factory()->superuser()->create()) + ->from(route('licenses.create')) + ->post(route('licenses.store'), [ + 'name' => 'Test Valid License', + 'seats' => '100000', + 'category_id' => Category::factory()->forLicenses()->create()->id, + ]); + $response->assertStatus(302); + $license = License::where('name', 'Test Valid License')->first(); + $this->assertNull($license); + //$license->assetlog()->has_one_of_(); +// $this->assertDatabaseMissing('action_logs', ['action_type' => 'create', 'item_id' => $license->id, 'item_type' => License::class]); +// $this->assertDatabaseMissing('action_logs', ['action_type' => 'add seats', 'item_id' => $license->id, 'item_type' => License::class]); + //test log entries? Sure. + + } + + } diff --git a/tests/Feature/Licenses/Ui/UpdateLicenseTest.php b/tests/Feature/Licenses/Ui/UpdateLicenseTest.php index 7b1b5b29e3..46c4f70785 100644 --- a/tests/Feature/Licenses/Ui/UpdateLicenseTest.php +++ b/tests/Feature/Licenses/Ui/UpdateLicenseTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Licenses\Ui; +use App\Models\Category; use App\Models\License; use App\Models\User; use Tests\TestCase; @@ -14,4 +15,90 @@ class UpdateLicenseTest extends TestCase ->get(route('licenses.edit', License::factory()->create()->id)) ->assertOk(); } + + public function testCanUpdateLicenseSeats() + { + $admin = User::factory()->superuser()->create(); + $license_category = Category::factory()->forLicenses()->create()->id; + $response = $this->actingAs($admin) + ->from(route('licenses.create')) + ->post(route('licenses.store'), [ + 'name' => 'Test Update License', + 'seats' => '9999', + 'category_id' => $license_category, + ]); + $response->assertStatus(302); + $license = License::where('name', 'Test Update License')->sole(); + $this->assertNotNull($license); + + $this->actingAs($admin) + ->put(route('licenses.update', $license->id), [ + 'name' => 'Test Update License', + 'seats' => '19999', + 'category_id' => $license_category, + ]) + ->assertStatus(302); + + $license->refresh(); + $this->assertEquals($license->licenseseats()->count(), $license->seats); + $this->assertEquals($license->licenseseats()->count(), 19999); + } + + public function testCannotUpdateLicenseSeatsTooMuch() + { + $admin = User::factory()->superuser()->create(); + $license_category = Category::factory()->forLicenses()->create()->id; + $response = $this->actingAs($admin) + ->from(route('licenses.create')) + ->post(route('licenses.store'), [ + 'name' => 'Test Update License', + 'seats' => '9999', + 'category_id' => $license_category, + ]); + $response->assertStatus(302); + $license = License::where('name', 'Test Update License')->sole(); + $this->assertNotNull($license); + + $this->actingAs($admin) + ->put(route('licenses.update', $license->id), [ + 'name' => 'Test Update License', + 'seats' => '29999', + 'category_id' => $license_category, + ]) + ->assertStatus(302); + + $license->refresh(); + $this->assertEquals($license->licenseseats()->count(), $license->seats); + $this->assertEquals($license->licenseseats()->count(), 9999); + } + + public function testCanRemoveLicenseSeats() + { + $admin = User::factory()->superuser()->create(); + $license_category = Category::factory()->forLicenses()->create()->id; + $response = $this->actingAs($admin) + ->from(route('licenses.create')) + ->post(route('licenses.store'), [ + 'name' => 'Test Remove License Seats', + 'seats' => '9999', + 'category_id' => $license_category, + ]); + $response->assertStatus(302); + $license = License::where('name', 'Test Remove License Seats')->sole(); + $this->assertNotNull($license); + + $this->actingAs($admin) + ->put(route('licenses.update', $license->id), [ + 'name' => 'Test Remove License Seats', + 'seats' => '5000', + 'category_id' => $license_category, + ]) + ->assertStatus(302); + + $license->refresh(); + $this->assertEquals($license->licenseseats()->count(), $license->seats); + $this->assertEquals($license->licenseseats()->count(), 5000); + } + + }