From b5edbb8ec04dc0ebf68e16770ae53c30781d356d Mon Sep 17 00:00:00 2001 From: Joel Male Date: Wed, 27 May 2026 21:24:09 +1000 Subject: [PATCH] feat: add TaxRule base class --- src/Tax/TaxRule.php | 48 ++++++++++++++++++++++++ tests/Unit/Tax/TaxRuleTest.php | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/Tax/TaxRule.php create mode 100644 tests/Unit/Tax/TaxRuleTest.php diff --git a/src/Tax/TaxRule.php b/src/Tax/TaxRule.php new file mode 100644 index 0000000..d1422f2 --- /dev/null +++ b/src/Tax/TaxRule.php @@ -0,0 +1,48 @@ +isApplicable()) { + throw new InvalidTaxRuleException("Tax rule [{$this->name}] is not applicable."); + } + + $data = [ + 'name' => $this->name, + 'type' => 'tax', + 'value' => $this->value, + 'target' => $this->target, + ]; + + if ($this->minimum !== null) { + $data['minimum'] = $this->minimum; + } + + if ($this->maximum !== null) { + $data['maximum'] = $this->maximum; + } + + return new CartCondition($data); + } +} diff --git a/tests/Unit/Tax/TaxRuleTest.php b/tests/Unit/Tax/TaxRuleTest.php new file mode 100644 index 0000000..368a79f --- /dev/null +++ b/tests/Unit/Tax/TaxRuleTest.php @@ -0,0 +1,68 @@ +toCondition(); + + expect($condition)->toBeInstanceOf(CartCondition::class); + expect($condition->getName())->toBe('GST'); + expect($condition->getValue())->toBe('10%'); + expect($condition->getType())->toBe('tax'); + expect($condition->getTarget())->toBe('subtotal'); + }); + + test('isApplicable() returning false causes toCondition() to throw', function () { + expect(fn() => (new NotApplicableTax)->toCondition()) + ->toThrow(InvalidTaxRuleException::class); + }); + + test('supports total as target', function () { + $tax = new class extends TaxRule { + protected string $name = 'Sales Tax'; + protected string $value = '8%'; + protected string $target = 'total'; + public function isApplicable(): bool { return true; } + }; + + expect($tax->toCondition()->getTarget())->toBe('total'); + }); + + test('supports minimum threshold', function () { + $tax = new class extends TaxRule { + protected string $name = 'Luxury Tax'; + protected string $value = '15%'; + protected ?float $minimum = 500.0; + public function isApplicable(): bool { return true; } + }; + + expect($tax->toCondition()->getMinimum())->toBe(500.0); + }); +});