create(); $bucket = Bucket::factory()->create([ 'scenario_id' => $scenario->id, 'starting_amount' => 100000, // $1000 in cents 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, ]); // Create draws and outflows directly Draw::create([ 'bucket_id' => $bucket->id, 'amount' => 50000, // $500 in cents 'date' => now(), 'description' => 'Test draw', 'is_projected' => false, ]); Outflow::create([ 'stream_id' => null, // We'll make this nullable for test 'bucket_id' => $bucket->id, 'amount' => 20000, // $200 in cents 'date' => now(), 'description' => 'Test outflow', 'is_projected' => false, ]); // Act & Assert // starting_amount (100000) + draws (50000) - outflows (20000) = 130000 $this->assertEquals(130000, $bucket->getCurrentBalance()); } public function test_current_balance_without_starting_amount_defaults_to_zero() { // Arrange $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->create([ 'scenario_id' => $scenario->id, 'starting_amount' => 0, // $0 in cents 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, ]); // Create draws and outflows directly Draw::create([ 'bucket_id' => $bucket->id, 'amount' => 30000, // $300 in cents 'date' => now(), 'description' => 'Test draw', 'is_projected' => false, ]); Outflow::create([ 'stream_id' => null, // We'll make this nullable for test 'bucket_id' => $bucket->id, 'amount' => 10000, // $100 in cents 'date' => now(), 'description' => 'Test outflow', 'is_projected' => false, ]); // Act & Assert // starting_amount (0) + draws (30000) - outflows (10000) = 20000 $this->assertEquals(20000, $bucket->getCurrentBalance()); } public function test_effective_capacity_with_zero_buffer_equals_allocation_value(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'buffer_multiplier' => 0, ]); $this->assertEquals(50000, $bucket->getEffectiveCapacity()); } public function test_effective_capacity_with_full_buffer_doubles_capacity(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'buffer_multiplier' => 1.0, ]); $this->assertEquals(100000, $bucket->getEffectiveCapacity()); } public function test_effective_capacity_with_half_buffer(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'buffer_multiplier' => 0.5, ]); $this->assertEquals(75000, $bucket->getEffectiveCapacity()); } public function test_effective_capacity_for_percentage_returns_php_float_max(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->percentage(2500)->create([ 'scenario_id' => $scenario->id, 'buffer_multiplier' => 1.0, ]); $this->assertEquals(PHP_INT_MAX, $bucket->getEffectiveCapacity()); } public function test_effective_capacity_for_unlimited_returns_php_float_max(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->unlimited()->create([ 'scenario_id' => $scenario->id, 'buffer_multiplier' => 1.0, ]); $this->assertEquals(PHP_INT_MAX, $bucket->getEffectiveCapacity()); } public function test_has_available_space_uses_effective_capacity(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'starting_amount' => 50000, 'buffer_multiplier' => 1.0, ]); // Balance is 50000, effective capacity is 100000 — still has space $this->assertTrue($bucket->hasAvailableSpace()); } public function test_has_available_space_false_when_at_effective_capacity(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'starting_amount' => 100000, 'buffer_multiplier' => 1.0, ]); // Balance is 100000, effective capacity is 100000 — no space $this->assertFalse($bucket->hasAvailableSpace()); } public function test_get_available_space_uses_effective_capacity(): void { $scenario = Scenario::factory()->create(); $bucket = Bucket::factory()->fixedLimit(50000)->create([ 'scenario_id' => $scenario->id, 'starting_amount' => 30000, 'buffer_multiplier' => 1.0, ]); // Effective capacity 100000 - balance 30000 = 70000 available $this->assertEquals(70000, $bucket->getAvailableSpace()); } }