16 - Update tests for integer allocation_value

This commit is contained in:
myrmidex 2026-03-21 17:42:52 +01:00
parent 3a5126f51c
commit d6f60ab987
5 changed files with 52 additions and 75 deletions

View file

@ -23,7 +23,7 @@ protected function setUp(): void
public function test_can_update_starting_amount_only(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'starting_amount' => 0,
'priority' => 1,
@ -44,7 +44,7 @@ public function test_can_update_starting_amount_only(): void
public function test_can_update_type_only(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'priority' => 1,
]);
@ -63,7 +63,7 @@ public function test_can_update_type_only(): void
public function test_can_update_buffer_multiplier_only(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'buffer_multiplier' => 0,
'priority' => 1,
@ -97,7 +97,7 @@ public function test_cannot_change_overflow_type(): void
public function test_starting_amount_rejects_negative(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'priority' => 1,
]);
@ -112,7 +112,7 @@ public function test_starting_amount_rejects_negative(): void
public function test_buffer_multiplier_forced_to_zero_for_non_fixed_limit(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'buffer_multiplier' => 1.5,
'priority' => 1,
@ -120,7 +120,7 @@ public function test_buffer_multiplier_forced_to_zero_for_non_fixed_limit(): voi
$response = $this->patchJson("/buckets/{$bucket->uuid}", [
'allocation_type' => 'percentage',
'allocation_value' => 25,
'allocation_value' => 2500,
]);
$response->assertOk();
@ -133,7 +133,7 @@ public function test_buffer_multiplier_forced_to_zero_for_non_fixed_limit(): voi
public function test_response_includes_starting_amount(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'starting_amount' => 500,
'priority' => 1,
@ -150,7 +150,7 @@ public function test_response_includes_starting_amount(): void
public function test_can_update_name_only(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'name' => 'Old Name',
'priority' => 1,
@ -169,7 +169,7 @@ public function test_can_update_name_only(): void
public function test_partial_update_does_not_null_other_fields(): void
{
$bucket = Bucket::factory()->need()->fixedLimit(1000)->create([
$bucket = Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'starting_amount' => 500,
'buffer_multiplier' => 1.5,
@ -183,7 +183,7 @@ public function test_partial_update_does_not_null_other_fields(): void
$response->assertOk();
$bucket->refresh();
$this->assertEquals(750, $bucket->starting_amount);
$this->assertEquals(1000, (float) $bucket->allocation_value);
$this->assertEquals(100000, $bucket->allocation_value);
$this->assertEquals(1.5, (float) $bucket->buffer_multiplier);
}
}

View file

@ -21,9 +21,6 @@ protected function setUp(): void
public function test_preview_returns_correct_allocations(): void
{
// allocation_value is in dollars, but PipelineAllocationService treats
// getEffectiveCapacity() return as cents (known unit mismatch).
// fixedLimit(50000) = $500 capacity as seen by the service.
Bucket::factory()->need()->fixedLimit(50000)->create([
'scenario_id' => $this->scenario->id,
'name' => 'Rent',
@ -38,26 +35,24 @@ public function test_preview_returns_correct_allocations(): void
'starting_amount' => 0,
]);
// Send 70000 cents = $700
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 700]
['amount' => 70000]
);
$response->assertOk();
$response->assertJsonCount(2, 'allocations');
$response->assertJsonPath('allocations.0.bucket_name', 'Rent');
$response->assertJsonPath('allocations.0.allocated_amount', 500);
$response->assertJsonPath('allocations.0.allocated_amount', 50000);
$response->assertJsonPath('allocations.1.bucket_name', 'Fun');
$response->assertJsonPath('allocations.1.allocated_amount', 200);
$response->assertJsonPath('total_allocated', 700);
$response->assertJsonPath('allocations.1.allocated_amount', 20000);
$response->assertJsonPath('total_allocated', 70000);
$response->assertJsonPath('unallocated', 0);
}
public function test_preview_returns_remaining_capacity(): void
{
// fixedLimit(50000) → getEffectiveCapacity() = 50000 (treated as cents by service)
// Input $300 = 30000 cents, allocated = min(50000, 30000) = 30000 cents = $300
// remaining = (50000 - 30000) / 100 = $200
Bucket::factory()->need()->fixedLimit(50000)->create([
'scenario_id' => $this->scenario->id,
'name' => 'Savings',
@ -65,14 +60,15 @@ public function test_preview_returns_remaining_capacity(): void
'starting_amount' => 0,
]);
// Send 30000 cents = $300
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 300]
['amount' => 30000]
);
$response->assertOk();
$response->assertJsonPath('allocations.0.allocated_amount', 300);
$response->assertJsonPath('allocations.0.remaining_capacity', 200);
$response->assertJsonPath('allocations.0.allocated_amount', 30000);
$response->assertJsonPath('allocations.0.remaining_capacity', 20000);
}
public function test_preview_returns_uuids_not_integer_ids(): void
@ -85,7 +81,7 @@ public function test_preview_returns_uuids_not_integer_ids(): void
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 100]
['amount' => 10000]
);
$response->assertOk();
@ -102,7 +98,7 @@ public function test_preview_includes_bucket_type(): void
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 100]
['amount' => 10000]
);
$response->assertOk();
@ -146,13 +142,13 @@ public function test_preview_with_no_buckets_returns_empty_allocations(): void
{
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 1000]
['amount' => 100000]
);
$response->assertOk();
$response->assertJsonPath('allocations', []);
$response->assertJsonPath('total_allocated', 0);
$response->assertJsonPath('unallocated', 1000);
$response->assertJsonPath('unallocated', 100000);
}
public function test_preview_respects_priority_ordering(): void
@ -173,33 +169,14 @@ public function test_preview_respects_priority_ordering(): void
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 400]
['amount' => 40000]
);
$response->assertOk();
$response->assertJsonPath('allocations.0.bucket_name', 'High Priority');
$response->assertJsonPath('allocations.0.allocated_amount', 300);
$response->assertJsonPath('allocations.0.allocated_amount', 30000);
$response->assertJsonPath('allocations.1.bucket_name', 'Low Priority');
$response->assertJsonPath('allocations.1.allocated_amount', 100);
}
public function test_preview_handles_dollar_cent_conversion_accurately(): void
{
Bucket::factory()->need()->fixedLimit(100000)->create([
'scenario_id' => $this->scenario->id,
'priority' => 1,
'starting_amount' => 0,
]);
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 15.50]
);
$response->assertOk();
$response->assertJsonPath('allocations.0.allocated_amount', 15.5);
$response->assertJsonPath('total_allocated', 15.5);
$response->assertJsonPath('unallocated', 0);
$response->assertJsonPath('allocations.1.allocated_amount', 10000);
}
public function test_preview_with_overflow_bucket_captures_remainder(): void
@ -220,16 +197,16 @@ public function test_preview_with_overflow_bucket_captures_remainder(): void
$response = $this->postJson(
"/scenarios/{$this->scenario->uuid}/projections/preview",
['amount' => 500]
['amount' => 50000]
);
$response->assertOk();
$response->assertJsonPath('allocations.0.bucket_name', 'Rent');
$response->assertJsonPath('allocations.0.allocated_amount', 200);
$response->assertJsonPath('allocations.0.allocated_amount', 20000);
$response->assertJsonPath('allocations.1.bucket_name', 'Overflow');
$response->assertJsonPath('allocations.1.allocated_amount', 300);
$response->assertJsonPath('allocations.1.allocated_amount', 30000);
$response->assertJsonPath('allocations.1.remaining_capacity', null);
$response->assertJsonPath('total_allocated', 500);
$response->assertJsonPath('total_allocated', 50000);
$response->assertJsonPath('unallocated', 0);
}
}

View file

@ -32,14 +32,14 @@ public function test_can_create_fixed_limit_bucket(): void
$this->scenario,
'Test Bucket',
BucketAllocationTypeEnum::FIXED_LIMIT,
allocationValue: 1000.00
allocationValue: 100000
);
$this->assertInstanceOf(Bucket::class, $bucket);
$this->assertEquals('Test Bucket', $bucket->name);
$this->assertEquals(BucketTypeEnum::NEED, $bucket->type);
$this->assertEquals(BucketAllocationTypeEnum::FIXED_LIMIT, $bucket->allocation_type);
$this->assertEquals(1000.00, $bucket->allocation_value);
$this->assertEquals(100000, $bucket->allocation_value);
$this->assertEquals(1, $bucket->priority);
$this->assertEquals(1, $bucket->sort_order);
$this->assertEquals($this->scenario->id, $bucket->scenario_id);
@ -51,11 +51,11 @@ public function test_can_create_percentage_bucket(): void
$this->scenario,
'Percentage Bucket',
BucketAllocationTypeEnum::PERCENTAGE,
allocationValue: 25.5
allocationValue: 2550
);
$this->assertEquals(BucketAllocationTypeEnum::PERCENTAGE, $bucket->allocation_type);
$this->assertEquals(25.5, $bucket->allocation_value);
$this->assertEquals(2550, $bucket->allocation_value);
}
public function test_can_create_unlimited_overflow_bucket(): void
@ -79,7 +79,7 @@ public function test_unlimited_overflow_bucket_ignores_allocation_value(): void
'Overflow Bucket',
BucketAllocationTypeEnum::UNLIMITED,
BucketTypeEnum::OVERFLOW,
999.99
99999
);
$this->assertEquals(BucketAllocationTypeEnum::UNLIMITED, $bucket->allocation_type);
@ -279,26 +279,26 @@ public function test_throws_exception_for_percentage_without_allocation_value():
public function test_throws_exception_for_percentage_below_minimum(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Percentage allocation value must be between 0.01 and 100');
$this->expectExceptionMessage('Percentage allocation value must be between 1 and 10000');
$this->action->execute(
$this->scenario,
'Test Bucket',
BucketAllocationTypeEnum::PERCENTAGE,
allocationValue: 0.005
allocationValue: 0
);
}
public function test_throws_exception_for_percentage_above_maximum(): void
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Percentage allocation value must be between 0.01 and 100');
$this->expectExceptionMessage('Percentage allocation value must be between 1 and 10000');
$this->action->execute(
$this->scenario,
'Test Bucket',
BucketAllocationTypeEnum::PERCENTAGE,
allocationValue: 101
allocationValue: 10001
);
}
@ -391,7 +391,7 @@ public function test_buffer_multiplier_forced_to_zero_for_percentage_bucket(): v
$this->scenario,
'Percentage Bucket',
BucketAllocationTypeEnum::PERCENTAGE,
allocationValue: 25.0,
allocationValue: 2500,
bufferMultiplier: 1.0,
);

View file

@ -88,7 +88,7 @@ public function test_effective_capacity_with_zero_buffer_equals_allocation_value
'buffer_multiplier' => 0,
]);
$this->assertEquals(50000.0, $bucket->getEffectiveCapacity());
$this->assertEquals(50000, $bucket->getEffectiveCapacity());
}
public function test_effective_capacity_with_full_buffer_doubles_capacity(): void
@ -99,7 +99,7 @@ public function test_effective_capacity_with_full_buffer_doubles_capacity(): voi
'buffer_multiplier' => 1.0,
]);
$this->assertEquals(100000.0, $bucket->getEffectiveCapacity());
$this->assertEquals(100000, $bucket->getEffectiveCapacity());
}
public function test_effective_capacity_with_half_buffer(): void
@ -110,18 +110,18 @@ public function test_effective_capacity_with_half_buffer(): void
'buffer_multiplier' => 0.5,
]);
$this->assertEquals(75000.0, $bucket->getEffectiveCapacity());
$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(25)->create([
$bucket = Bucket::factory()->percentage(2500)->create([
'scenario_id' => $scenario->id,
'buffer_multiplier' => 1.0,
]);
$this->assertEquals(PHP_FLOAT_MAX, $bucket->getEffectiveCapacity());
$this->assertEquals(PHP_INT_MAX, $bucket->getEffectiveCapacity());
}
public function test_effective_capacity_for_unlimited_returns_php_float_max(): void
@ -132,7 +132,7 @@ public function test_effective_capacity_for_unlimited_returns_php_float_max(): v
'buffer_multiplier' => 1.0,
]);
$this->assertEquals(PHP_FLOAT_MAX, $bucket->getEffectiveCapacity());
$this->assertEquals(PHP_INT_MAX, $bucket->getEffectiveCapacity());
}
public function test_has_available_space_uses_effective_capacity(): void
@ -171,6 +171,6 @@ public function test_get_available_space_uses_effective_capacity(): void
]);
// Effective capacity 100000 - balance 30000 = 70000 available
$this->assertEquals(70000.0, $bucket->getAvailableSpace());
$this->assertEquals(70000, $bucket->getAvailableSpace());
}
}

View file

@ -102,7 +102,7 @@ public function test_percentage_bucket_gets_percentage_of_remaining_amount()
$percentageBucket = Bucket::factory()->create([
'scenario_id' => $this->scenario->id,
'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE,
'allocation_value' => 20.00, // 20%
'allocation_value' => 2000, // 20% in basis points
'starting_amount' => 0,
'priority' => 2,
]);
@ -183,7 +183,7 @@ public function test_handles_complex_mixed_bucket_scenario()
$percentage1 = Bucket::factory()->create([
'scenario_id' => $this->scenario->id,
'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE,
'allocation_value' => 15.00, // 15%
'allocation_value' => 1500, // 15% in basis points
'starting_amount' => 0,
'priority' => 2,
]);
@ -197,7 +197,7 @@ public function test_handles_complex_mixed_bucket_scenario()
$percentage2 = Bucket::factory()->create([
'scenario_id' => $this->scenario->id,
'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE,
'allocation_value' => 25.00, // 25%
'allocation_value' => 2500, // 25% in basis points
'starting_amount' => 0,
'priority' => 4,
]);
@ -326,7 +326,7 @@ public function test_percentage_allocation_with_insufficient_remaining_amount()
$percentageBucket = Bucket::factory()->create([
'scenario_id' => $this->scenario->id,
'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE,
'allocation_value' => 20.00, // 20%
'allocation_value' => 2000, // 20% in basis points
'starting_amount' => 0,
'priority' => 2,
]);
@ -381,7 +381,7 @@ public function test_buffer_does_not_affect_percentage_allocation(): void
Bucket::factory()->create([
'scenario_id' => $this->scenario->id,
'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE,
'allocation_value' => 25.00,
'allocation_value' => 2500, // 25% in basis points
'buffer_multiplier' => 1.0,
'starting_amount' => 0,
'priority' => 1,