From eb517a673ad3d1cbea84a39d91177bccbb8e8885 Mon Sep 17 00:00:00 2001 From: Morven Lewis-Everley Date: Mon, 28 Oct 2024 15:28:15 +0000 Subject: [PATCH] Add unit tests for customise and modify price --- tests/FactoryScaffold.yml | 273 ++++++++++++++++++++++++ tests/LineItemFactoryTest.php | 174 ++++++++++++++- tests/OrderFactoryTest.php | 20 +- tests/model/TestCustomisableProduct.php | 88 ++++++++ tests/model/TestCustomisation.php | 27 +++ tests/model/TestCustomisationOption.php | 24 +++ 6 files changed, 592 insertions(+), 14 deletions(-) create mode 100644 tests/FactoryScaffold.yml create mode 100644 tests/model/TestCustomisableProduct.php create mode 100644 tests/model/TestCustomisation.php create mode 100644 tests/model/TestCustomisationOption.php diff --git a/tests/FactoryScaffold.yml b/tests/FactoryScaffold.yml new file mode 100644 index 0000000..df61b71 --- /dev/null +++ b/tests/FactoryScaffold.yml @@ -0,0 +1,273 @@ +SilverCommerce\GeoZones\Model\Region: + bir: + Name: Birmingham + Code: BIR + CountryCode: GB + auk: + Name: Aukland + Code: AUK + CountryCode: NZ + al: + Name: Alabama + Code: AL + CountryCode: US + +SilverCommerce\GeoZones\Model\Zone: + uk: + Country: 'GB' + AllRegions: 1 + Enabled: 1 + nz: + Country: 'NZ' + AllRegions: 1 + Enabled: 1 + us: + Country: 'US' + AllRegions: 1 + Enabled: 1 + +SilverCommerce\TaxAdmin\Model\TaxRate: + vat: + ID: 1 + Title: "Test VAT" + Rate: 20 + Zones: =>SilverCommerce\GeoZones\Model\Zone.uk + reduced: + ID: 2 + Title: "Test Reduced Rate" + Rate: 5 + Zones: =>SilverCommerce\GeoZones\Model\Zone.nz + zero: + ID: 3 + Title: "Test Zero Rate" + Rate: 0 + Zones: =>SilverCommerce\GeoZones\Model\Zone.us + +SilverCommerce\TaxAdmin\Model\TaxCategory: + standard_goods: + Title: "Standard Goods" + Rates: + - =>SilverCommerce\TaxAdmin\Model\TaxRate.vat + - =>SilverCommerce\TaxAdmin\Model\TaxRate.reduced + - =>SilverCommerce\TaxAdmin\Model\TaxRate.zero + +SilverCommerce\CatalogueAdmin\Model\CatalogueProduct: + socks: + Title: "Socks" + StockID: "so1" + BasePrice: 5.99 + StockLevel: 10 + notax: + Title: "No Tax Item" + StockID: "nt1" + BasePrice: 6.50 + StockLevel: 10 + Weight: 0.5 + tax: + Title: "Tax Item" + StockID: "t1" + BasePrice: 5.99 + StockLevel: 10 + Weight: 0.75 + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.vat + categorised: + Title: "Categorised Item" + StockID: "ci1" + BasePrice: 4.65 + TaxCategory: =>SilverCommerce\TaxAdmin\Model\TaxCategory.standard_goods + +SilverCommerce\OrdersAdmin\Model\LineItemCustomisation: + freecustomisation: + Title: "Customisation" + Value: "Free" + Number: 12345 + expensivecustomisation: + Title: "Customisation" + Value: "Expensive" + +SilverCommerce\OrdersAdmin\Model\PriceModifier: + negativemodifier: + Name: "Negative" + ModifyPrice: -1.50 + positivemodifier: + Name: "Positive" + ModifyPrice: 0.75 + +SilverCommerce\OrdersAdmin\Model\LineItem: + deliverable: + Title: "Deliverable Item" + Deliverable: true + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + notdeliverable: + Title: "Non Deliverable Item" + Deliverable: false + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + notaxitem: + Title: "A cheap item" + Quantity: 2 + UnmodifiedPrice: 6.50 + StockID: "nt1" + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.zero # Zero + reducedtaxitem: + Title: "An item with reduced tax" + Quantity: 2 + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + UnmodifiedPrice: 5.99 # 0.2995 tax per item + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.reduced # Reduced + taxitemone: + Title: "A tax item" + Quantity: 2 + UnmodifiedPrice: 5.99 # 1.198 tax per item + StockID: "t1" + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.vat # VAT + taxitemtwo: + Title: "Another tax item" + Quantity: 2 + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + UnmodifiedPrice: 5.99 # 1.198 tax per item + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.vat # VAT + taxitemthree: + Title: "Two cheap items" + Quantity: 2 + Weight: 0.75 + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + UnmodifiedPrice: 3.99 # 0.798 tax per item + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.vat # VAT + sockitem: + Title: "Socks" + Quantity: 1 + Weight: 0.5 + StockID: "so1" + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + UnmodifiedPrice: 5.99 + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.zero # Zero + customitem: + Title: "Socks" + Quantity: 1 + Weight: 0.5 + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + UnmodifiedPrice: 5.99 + TaxRate: =>SilverCommerce\TaxAdmin\Model\TaxRate.zero # Zero + Customisations: + - =>SilverCommerce\OrdersAdmin\Model\LineItemCustomisation.freecustomisation + - =>SilverCommerce\OrdersAdmin\Model\LineItemCustomisation.expensivecustomisation + PriceModifications: + - =>SilverCommerce\OrdersAdmin\Model\PriceModifier.negativemodifier + - =>SilverCommerce\OrdersAdmin\Model\PriceModifier.positivemodifier + + taxtestableuk: + Title: "UK Tax Test item" + StockID: "ci1" + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + Quantity: 1 + UnmodifiedPrice: 5.50 + fixedtaxtestableuk: + Title: "UK Fixed Tax Test item" + StockID: "t1" + ProductClass: SilverCommerce\CatalogueAdmin\Model\CatalogueProduct + Quantity: 1 + UnmodifiedPrice: 5.99 + +SilverCommerce\OrdersAdmin\Model\Estimate: + addressdetails_uk: + Ref: 1231 + Address1: "123 Street Name" + Address2: "A Place" + City: "A City" + PostCode: "AB12 3AB" + County: "BIR" + Country: "GB" + DeliveryAddress1: "321 Street Name" + DeliveryCity: "Delivery City" + DeliveryPostCode: "ZX98 9XZ" + DeliveryCounty: "BIR" + DeliveryCountry: "GB" + Items: =>SilverCommerce\OrdersAdmin\Model\LineItem.taxtestableuk + addressdetails_uk_two: + Ref: 1232 + Address1: "123 Street Name" + Address2: "Another Place" + City: "A City" + PostCode: "BB55 5FG" + County: "BIR" + Country: "GB" + DeliveryAddress1: "96 Some Road" + DeliveryCity: "Delivery City" + DeliveryPostCode: "ZX98 9XZ" + DeliveryCounty: "BIR" + DeliveryCountry: "GB" + Items: =>SilverCommerce\OrdersAdmin\Model\LineItem.fixedtaxtestableuk + deliverable: + Ref: 1233 + Items: + - =>SilverCommerce\OrdersAdmin\Model\LineItem.notdeliverable + - =>SilverCommerce\OrdersAdmin\Model\LineItem.deliverable + notdeliverable: + Ref: 1234 + Items: =>SilverCommerce\OrdersAdmin\Model\LineItem.notdeliverable + standardnotax: + Ref: 1235 + Items: =>SilverCommerce\OrdersAdmin\Model\LineItem.notaxitem + standardtax: + Ref: 1236 + Items: =>SilverCommerce\OrdersAdmin\Model\LineItem.taxitemone + complextax: + Ref: 1237 + Items: + - =>SilverCommerce\OrdersAdmin\Model\LineItem.reducedtaxitem + - =>SilverCommerce\OrdersAdmin\Model\LineItem.taxitemtwo + +SilverCommerce\OrdersAdmin\Model\Invoice: + unpaid: + Ref: 5555 + +SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisableProduct: + predefined: + Title: "Product with predefined options" + BasePrice: 10.50 + StockID: prcus111 + freetext: + Title: "Product with freetext option" + BasePrice: 4.50 + StockID: prcus222 + chargable: + Title: "Product with chargable options" + BasePrice: 13.25 + StockID: prcus333 + +SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation: + colour: + Title: "Colour" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisableProduct.predefined + personalise: + Title: "Personalise" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisableProduct.freetext + size: + Title: "Size" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisableProduct.chargable + +SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisationOption: + colour_red: + Title: "Red" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.colour + colour_blue: + Title: "Blue" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.colour + colour_green: + Title: "Green" + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.colour + + size_sm: + Title: "Small" + ModifyPrice: 0.00 + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.size + size_md: + Title: "Medium" + ModifyPrice: 1.25 + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.size + size_lg: + Title: "Large" + ModifyPrice: 2.75 + Parent: =>SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation.size diff --git a/tests/LineItemFactoryTest.php b/tests/LineItemFactoryTest.php index c98079c..0ff08d8 100644 --- a/tests/LineItemFactoryTest.php +++ b/tests/LineItemFactoryTest.php @@ -10,12 +10,22 @@ use SilverCommerce\OrdersAdmin\Model\LineItem; use SilverCommerce\OrdersAdmin\Model\PriceModifier; use SilverCommerce\OrdersAdmin\Factory\LineItemFactory; +use SilverCommerce\OrdersAdmin\Tests\Model\TestProduct; use SilverCommerce\CatalogueAdmin\Model\CatalogueProduct; use SilverCommerce\OrdersAdmin\Model\LineItemCustomisation; +use SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation; +use SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisableProduct; +use SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisationOption; class LineItemFactoryTest extends SapphireTest { - protected static $fixture_file = 'OrdersScaffold.yml'; + protected static $fixture_file = 'FactoryScaffold.yml'; + + protected static $extra_dataobjects = [ + TestProduct::class, + TestCustomisation::class, + TestCustomisationOption::class + ]; /** * Add some extra functionality on construction @@ -206,6 +216,168 @@ public function testModifyPrice() $this->assertCount(1, $item->PriceModifications()); } + public function testAutomaticCustomisation() + { + $product = $this->objFromFixture( + TestCustomisableProduct::class, + 'predefined' + ); + $colour = $this->objFromFixture( + TestCustomisation::class, + 'colour' + ); + $red = $this->objFromFixture( + TestCustomisationOption::class, + 'colour_red' + ); + $blue = $this->objFromFixture( + TestCustomisationOption::class, + 'colour_blue' + ); + $green = $this->objFromFixture( + TestCustomisationOption::class, + 'colour_green' + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$colour->ID => $red->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->Customisations()); + $this->assertEquals( + 'Colour', + $item->Customisations()->first()->Title + ); + $this->assertEquals( + 'Red', + $item->Customisations()->first()->Value + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$colour->ID => $blue->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->Customisations()); + $this->assertEquals( + 'Colour', + $item->Customisations()->first()->Title + ); + $this->assertEquals( + 'Blue', + $item->Customisations()->first()->Value + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$colour->ID => $red->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->Customisations()); + $this->assertEquals( + 'Colour', + $item->Customisations()->first()->Title + ); + $this->assertEquals( + 'Red', + $item->Customisations()->first()->Value + ); + } + + public function testAutomaticPriceModification() + { + $product = $this->objFromFixture( + TestCustomisableProduct::class, + 'chargable' + ); + $size = $this->objFromFixture( + TestCustomisation::class, + 'size' + ); + $sm = $this->objFromFixture( + TestCustomisationOption::class, + 'size_sm' + ); + $md = $this->objFromFixture( + TestCustomisationOption::class, + 'size_md' + ); + $lg = $this->objFromFixture( + TestCustomisationOption::class, + 'size_lg' + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$size->ID => $sm->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->PriceModifications()); + $this->assertEquals( + 13.25, + $item->getNoTaxPrice() + ); + $this->assertEquals( + 'Size', + $item->PriceModifications()->first()->Title + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$size->ID => $md->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->PriceModifications()); + $this->assertEquals( + 14.50, + $item->getNoTaxPrice() + ); + $this->assertEquals( + 'Size', + $item->PriceModifications()->first()->Title + ); + + $factory = LineItemFactory::create() + ->setProduct($product) + ->setQuantity(1) + ->setExtraData([$size->ID => $lg->ID]) + ->makeItem() + ->write(); + + $item = $factory->getItem(); + + $this->assertCount(1, $item->PriceModifications()); + $this->assertEquals( + 16.00, + $item->getNoTaxPrice() + ); + $this->assertEquals( + 'Size', + $item->PriceModifications()->first()->Title + ); + } + public function testFindBestTaxRate() { // First test a static rate diff --git a/tests/OrderFactoryTest.php b/tests/OrderFactoryTest.php index 612698f..93b5250 100644 --- a/tests/OrderFactoryTest.php +++ b/tests/OrderFactoryTest.php @@ -8,23 +8,17 @@ use SilverCommerce\OrdersAdmin\Model\Estimate; use SilverCommerce\OrdersAdmin\Factory\OrderFactory; use SilverCommerce\OrdersAdmin\Tests\Model\TestProduct; +use SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisation; +use SilverCommerce\OrdersAdmin\Tests\Model\TestCustomisationOption; class OrderFactoryTest extends SapphireTest { - /** - * Add some scaffold order records - * - * @var string - */ - protected static $fixture_file = 'OrdersScaffold.yml'; - - /** - * Setup test only objects - * - * @var array - */ + protected static $fixture_file = 'FactoryScaffold.yml'; + protected static $extra_dataobjects = [ - TestProduct::class + TestProduct::class, + TestCustomisation::class, + TestCustomisationOption::class ]; public function testFindBestPrefix() diff --git a/tests/model/TestCustomisableProduct.php b/tests/model/TestCustomisableProduct.php new file mode 100644 index 0000000..7e2fed9 --- /dev/null +++ b/tests/model/TestCustomisableProduct.php @@ -0,0 +1,88 @@ + TestCustomisation::class + ]; + + public function modifyItemPrice( + LineItemFactory $factory, + array $data = [] + ): SS_List { + $items = ArrayList::create(); + $item = $factory->getItem(); + $product = $item->findStockItem(); + + foreach ($data as $id => $value) { + $customisation = $product->Customisations()->byID($id); + + if (empty($customisation)) { + continue; + } + + $option = $customisation + ->Options() + ->byID($value); + + if (empty($option)) { + continue; + } + + $factory->modifyPrice( + $customisation->Title, + (float)$option->ModifyPrice, + $product + ); + } + + return $items; + } + + public function customiseLineItem( + LineItemFactory $factory, + array $data = [] + ): SS_List { + $items = ArrayList::create(); + $item = $factory->getItem(); + $product = $item->findStockItem(); + + foreach ($data as $id => $value) { + $customisation = $product + ->Customisations() + ->byID($id); + + if (empty($customisation)) { + continue; + } + + $option = $customisation + ->Options() + ->byID($value); + + if (empty($option)) { + continue; + } + + $factory->customise( + $customisation->Title, + $option->Title, + [], + $customisation + ); + } + + return $items; + } +} diff --git a/tests/model/TestCustomisation.php b/tests/model/TestCustomisation.php new file mode 100644 index 0000000..7d9c56e --- /dev/null +++ b/tests/model/TestCustomisation.php @@ -0,0 +1,27 @@ + 'Varchar' + ]; + + private static $has_one = [ + 'Parent' => TestCustomisableProduct::class + ]; + + private static $has_many = [ + 'Options' => TestCustomisationOption::class + ]; +} \ No newline at end of file diff --git a/tests/model/TestCustomisationOption.php b/tests/model/TestCustomisationOption.php new file mode 100644 index 0000000..8471f71 --- /dev/null +++ b/tests/model/TestCustomisationOption.php @@ -0,0 +1,24 @@ + 'Varchar', + 'ModifyPrice' => 'Decimal' + ]; + + private static $has_one = [ + "Parent" => TestCustomisation::class + ]; + + private static $default_sort = 'Sort ASC'; +}