From 958db6357bb9a5cb9adf95e787348e0b172ec311 Mon Sep 17 00:00:00 2001 From: "@ChristelLoftus" <christel@bob.co.za> Date: Mon, 19 Aug 2024 14:38:08 +0200 Subject: [PATCH] unit tests --- Helper/Data.php | 6 + Model/Carrier/AdditionalInfo.php | 1 - Model/Carrier/BobGo.php | 55 ++--- Model/Carrier/uSubs.php | 3 +- .../Checkout/Block/LayoutProcessorPlugin.php | 50 +++-- .../System/Config/Form/Field/VersionTest.php | 91 ++++++++ Test/Unit/Helper/DataTest.php | 166 +++++++++++++++ .../Unit/Model/Carrier/AdditionalInfoTest.php | 130 ++++++++++++ Test/Unit/Model/Carrier/BobGoTest.php | 194 ++++++++++++++++++ Test/Unit/Model/Carrier/USubsTest.php | 70 +++++++ Test/Unit/Model/Source/FreemethodTest.php | 42 ++++ Test/Unit/Model/Source/GenericTest.php | 67 ++++++ .../Observer/ConfigChangeObserverTest.php | 117 +++++++++++ .../Plugin/AddWeightUnitToOrderPluginTest.php | 97 +++++++++ .../Tracking/ChangeTitleTest.php | 62 ++++++ .../Block/Tracking/PopUpDeliveryDateTest.php | 80 ++++++++ .../Block/LayoutProcessorPluginTest.php | 85 ++++++++ 17 files changed, 1274 insertions(+), 42 deletions(-) create mode 100644 Test/Unit/Block/System/Config/Form/Field/VersionTest.php create mode 100644 Test/Unit/Helper/DataTest.php create mode 100644 Test/Unit/Model/Carrier/AdditionalInfoTest.php create mode 100644 Test/Unit/Model/Carrier/BobGoTest.php create mode 100644 Test/Unit/Model/Carrier/USubsTest.php create mode 100644 Test/Unit/Model/Source/FreemethodTest.php create mode 100644 Test/Unit/Model/Source/GenericTest.php create mode 100644 Test/Unit/Observer/ConfigChangeObserverTest.php create mode 100644 Test/Unit/Plugin/AddWeightUnitToOrderPluginTest.php create mode 100644 Test/Unit/Plugin/Block/DataProviders/Tracking/ChangeTitleTest.php create mode 100644 Test/Unit/Plugin/Block/Tracking/PopUpDeliveryDateTest.php create mode 100644 Test/Unit/Plugin/Checkout/Block/LayoutProcessorPluginTest.php diff --git a/Helper/Data.php b/Helper/Data.php index e4a613c..0abc58e 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -30,6 +30,12 @@ class Data extends AbstractHelper */ protected ModuleListInterface $_moduleList; + /** + * Constructor + * + * @param Context $context + * @param ModuleListInterface $moduleList + */ public function __construct( Context $context, ModuleListInterface $moduleList diff --git a/Model/Carrier/AdditionalInfo.php b/Model/Carrier/AdditionalInfo.php index 9f50431..2c82b4f 100644 --- a/Model/Carrier/AdditionalInfo.php +++ b/Model/Carrier/AdditionalInfo.php @@ -109,4 +109,3 @@ class AdditionalInfo return is_array($data) ? $data : []; } } - diff --git a/Model/Carrier/BobGo.php b/Model/Carrier/BobGo.php index b30e76c..345327a 100644 --- a/Model/Carrier/BobGo.php +++ b/Model/Carrier/BobGo.php @@ -288,7 +288,8 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car } } - if (!$errorMsg && !$rateRequest->getDestPostcode() && $this->isZipCodeRequired($rateRequest->getDestCountryId())) { + if (!$errorMsg && !$rateRequest->getDestPostcode() + && $this->isZipCodeRequired($rateRequest->getDestCountryId())) { $errorMsg = __('This shipping method is not available. Please specify the zip code.'); } @@ -572,7 +573,6 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car return $this->_rawTrackingRequest; } - /** * Send request for tracking * @@ -626,7 +626,6 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car } } - /** * Get tracking response * @@ -651,10 +650,10 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car } } - // Handle \Magento\Shipping\Model\Rate\Result if needed - if ($this->_result instanceof \Magento\Shipping\Model\Rate\Result) { - // Implement the logic for Rate\Result if applicable - } +// // Handle \Magento\Shipping\Model\Rate\Result if needed +// if ($this->_result instanceof \Magento\Shipping\Model\Rate\Result) { +// // Implement the logic for Rate\Result if applicable +// } if (trim($statuses) === '') { $statuses = (string)__('Empty response'); @@ -663,7 +662,6 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car return $statuses; } - /** * Get allowed shipping methods * @@ -706,9 +704,9 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car */ public function rollBack($data): bool { - // Ensure that $data is an array if needed, but keep the parameter type as mixed to match the parent class. - if (is_array($data)) { - // Your logic that operates on the array can go here. + // Return false if $data is not an array + if (!is_array($data)) { + return false; } return true; @@ -881,7 +879,8 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car if (is_array($rates)) { $this->_formatRates($rates, $result); } else { - $this->_logger->error('Bob Go API returned an invalid response: expected an array but received ' . gettype($rates)); + $this->_logger->error('Bob Go API returned an invalid response: + expected an array but received ' . gettype($rates)); } } @@ -889,7 +888,8 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car * Perform API Request for Shipment Tracking to Bob Go API and return response. * * @param string $trackInfo The tracking information or tracking ID. - * @param array<string, array<int, array<string, string>>> $result The result array to be populated with tracking details. + * @param array<string, array<int, array<string, string>>> $result The result array to be + * populated with tracking details. * @return array<string, array<int, array<string, string>>> The updated result array with tracking details. */ private function _requestTracking(string $trackInfo, array $result): array @@ -981,15 +981,15 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car * Prepare received checkpoints and activity from Bob Go Shipment Tracking API. * * @param array<string, mixed> $response The API response containing tracking checkpoints. - * @param array<string, array<int, array<string, string>>> $result The result array to be populated with activity details. + * @param array<string, array<int, array<string, string>>> $result The result array to be + * populated with activity details. * @return array<string, array<int, array<string, string>>> The updated result array with activity details. */ private function prepareActivity(array $response, array $result): array { if (isset($response['checkpoints']) && is_array($response['checkpoints'])) { foreach ($response['checkpoints'] as $checkpoint) { - if ( - is_array($checkpoint) && + if (is_array($checkpoint) && isset($checkpoint['status'], $checkpoint['time']) && is_string($checkpoint['status']) && is_string($checkpoint['time']) @@ -1057,9 +1057,10 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car * Build the payload for Bob Go API request and return the response. * * @param array<string, mixed> $payload The payload for the API request. - * @return array<int|string, mixed>|null The decoded response, or null if the response could not be decoded or is not an array. + * @return array<int|string, mixed>|null The decoded response, or null if the response could not be decoded + * or is not an array. */ - protected function uRates(array $payload): array|null + protected function uRates(array $payload): ?array { $this->curl->addHeader('Content-Type', 'application/json'); @@ -1174,15 +1175,18 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car /** * Processes the items in the cart, calculates their weights, and prepares an array of item details. * - * @param array<int, \Magento\Quote\Model\Quote\Item> $items The items in the cart. - * @param string $weightUnit The unit of weight used for the items. - * @param array<int, array<string, mixed>> $itemsArray The array to store the processed item details. - * @return array<int, array<string, mixed>> The array containing details of each item including SKU, quantity, price, and weight. + * @param \Magento\Quote\Model\Quote\Item[] $items The items in the cart. + * @param string $weightUnit The unit of weight used for the items. + * @param array<int, array<string, mixed>> $itemsArray The array to store the processed item details. + * @return array<int, array<string, mixed>> The array containing details of each item, + * including SKU, quantity, price, and weight. */ - public function getStoreItems(array $items, string $weightUnit, array $itemsArray): array - { + public function getStoreItems( + array $items, + string $weightUnit, + array $itemsArray + ): array { foreach ($items as $item) { - $mass = $this->getItemWeight($weightUnit, $item); $itemsArray[] = [ @@ -1192,6 +1196,7 @@ class BobGo extends AbstractCarrierOnline implements \Magento\Shipping\Model\Car 'weight' => round($mass), ]; } + return $itemsArray; } diff --git a/Model/Carrier/uSubs.php b/Model/Carrier/uSubs.php index e8f7264..da714ee 100644 --- a/Model/Carrier/uSubs.php +++ b/Model/Carrier/uSubs.php @@ -34,7 +34,8 @@ class USubs $data = json_decode($this->getRequestBody(), true); // Ensure that $data is an array and has the expected structure - if (is_array($data) && isset($data['address']) && is_array($data['address']) && isset($data['address']['company'])) { + if (is_array($data) && isset($data['address']) && is_array($data['address']) + && isset($data['address']['company'])) { return $data['address']['company']; } diff --git a/Plugin/Checkout/Block/LayoutProcessorPlugin.php b/Plugin/Checkout/Block/LayoutProcessorPlugin.php index 57f3d5a..e3e4a0e 100644 --- a/Plugin/Checkout/Block/LayoutProcessorPlugin.php +++ b/Plugin/Checkout/Block/LayoutProcessorPlugin.php @@ -18,27 +18,47 @@ class LayoutProcessorPlugin /** * Modify checkout layout to add suburb field. * - * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject - * @param array<string, mixed> $jsLayout - * @return array<string, mixed> + * @param LayoutProcessor $subject + * @param array<string, mixed> $jsLayout The JS layout array to be modified. + * @return array<string, mixed> The modified JS layout array. */ public function afterProcess( - \Magento\Checkout\Block\Checkout\LayoutProcessor $subject, + LayoutProcessor $subject, array $jsLayout ): array { $suburbAttribute = 'suburb'; - if (isset($jsLayout['components']) && is_array($jsLayout['components']) - && isset($jsLayout['components']['checkout']) && is_array($jsLayout['components']['checkout']) - && isset($jsLayout['components']['checkout']['children']) && is_array($jsLayout['components']['checkout']['children']) - && isset($jsLayout['components']['checkout']['children']['steps']) && is_array($jsLayout['components']['checkout']['children']['steps']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']) - && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']) && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'])) { + if (isset($jsLayout['components']) + && is_array($jsLayout['components']) + && isset($jsLayout['components']['checkout']) + && is_array($jsLayout['components']['checkout']) + && isset($jsLayout['components']['checkout']['children']) + && is_array($jsLayout['components']['checkout']['children']) + && isset($jsLayout['components']['checkout']['children']['steps']) + && is_array($jsLayout['components']['checkout']['children']['steps']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] + ['children']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] + ['shippingAddress']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] + ['children']['shippingAddress']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] + ['shippingAddress']['children']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] + ['children']['shippingAddress']['children']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] + ['shippingAddress']['children']['shipping-address-fieldset']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] + ['children']['shippingAddress']['children']['shipping-address-fieldset']) + && isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] + ['shippingAddress']['children']['shipping-address-fieldset']['children']) + && is_array($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step'] + ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'])) { $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children'] ['shippingAddress']['children']['shipping-address-fieldset']['children'][$suburbAttribute] = [ diff --git a/Test/Unit/Block/System/Config/Form/Field/VersionTest.php b/Test/Unit/Block/System/Config/Form/Field/VersionTest.php new file mode 100644 index 0000000..b031749 --- /dev/null +++ b/Test/Unit/Block/System/Config/Form/Field/VersionTest.php @@ -0,0 +1,91 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Block\System\Config\Form\Field; + +use BobGroup\BobGo\Block\System\Config\Form\Field\Version; +use BobGroup\BobGo\Helper\Data; +use Magento\Framework\Data\Form\Element\AbstractElement; +use Magento\Backend\Block\Template\Context; +use PHPUnit\Framework\TestCase; + +class VersionTest extends TestCase +{ + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $helperMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $contextMock; + + /** + * @var Version + */ + private $versionBlock; + + protected function setUp(): void + { + $this->helperMock = $this->createMock(Data::class); + $this->contextMock = $this->createMock(Context::class); + + // Instantiate the Version block + $this->versionBlock = new Version($this->contextMock, $this->helperMock); + } + + private function callProtectedMethod($object, $methodName, array $parameters = []) + { + $reflection = new \ReflectionClass($object); + $method = $reflection->getMethod($methodName); + $method->setAccessible(true); + + return $method->invokeArgs($object, $parameters); + } + + public function testGetElementHtml() + { + // Mock the AbstractElement + $elementMock = $this->createMock(AbstractElement::class); + + // Set up the helper mock to return a specific version + $this->helperMock->method('getExtensionVersion')->willReturn('1.0.0'); + + // Set the expectation for the setData method to set the 'value' + $elementMock->expects($this->once()) + ->method('setData') + ->with('value', '<a href="https://www.bobgo.co.za" title="BobGo" target="_blank">1.0.0</a>'); + + // Mock the getData method to return the value that was set + $elementMock->method('getData') + ->with('value') + ->willReturn('<a href="https://www.bobgo.co.za" title="BobGo" target="_blank">1.0.0</a>'); + + // Call the protected _getElementHtml method using reflection + $result = $this->callProtectedMethod($this->versionBlock, '_getElementHtml', [$elementMock]); + + // Assert that the result is the expected HTML string + $expectedHtml = '<a href="https://www.bobgo.co.za" title="BobGo" target="_blank">1.0.0</a>'; + $this->assertEquals($expectedHtml, $result); + } + + public function testGetElementHtmlWithNonStringValue() + { + // Mock the AbstractElement + $elementMock = $this->createMock(AbstractElement::class); + + // Set up the helper mock to return a specific version + $this->helperMock->method('getExtensionVersion')->willReturn('1.0.0'); + + // Return a non-string value for the 'value' key + $elementMock->method('getData') + ->with('value') + ->willReturn(['not_a_string']); + + // Call the protected _getElementHtml method using reflection + $result = $this->callProtectedMethod($this->versionBlock, '_getElementHtml', [$elementMock]); + + // Assert that the result is an empty string + $this->assertEquals('', $result); + } +} diff --git a/Test/Unit/Helper/DataTest.php b/Test/Unit/Helper/DataTest.php new file mode 100644 index 0000000..1063ae1 --- /dev/null +++ b/Test/Unit/Helper/DataTest.php @@ -0,0 +1,166 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Helper; + +use BobGroup\BobGo\Helper\Data; +use Magento\Framework\App\Helper\Context; +use Magento\Framework\Module\ModuleListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class DataTest extends TestCase +{ + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $contextMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $moduleListMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $scopeConfigMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $loggerMock; + + /** + * @var Data + */ + private $helper; + + protected function setUp(): void + { + $this->contextMock = $this->createMock(Context::class); + $this->moduleListMock = $this->createMock(ModuleListInterface::class); + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $this->loggerMock = $this->createMock(LoggerInterface::class); + + $this->contextMock->method('getLogger')->willReturn($this->loggerMock); + $this->contextMock->method('getScopeConfig')->willReturn($this->scopeConfigMock); + + // Instantiate the Data helper + $this->helper = new Data($this->contextMock, $this->moduleListMock); + } + + public function testIsEnabled() + { + // Mock the scopeConfig to return '1' when checking if the module is enabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE) + ->willReturn('1'); + + $result = $this->helper->isEnabled(); + $this->assertEquals('1', $result); + } + + public function testIsEnabledReturnsNullWhenDisabled() + { + // Mock the scopeConfig to return null when the module is disabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE) + ->willReturn(null); + + $result = $this->helper->isEnabled(); + $this->assertNull($result); + } + + public function testGetDebugStatus() + { + // Mock the scopeConfig to return '1' when checking if debug is enabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_DEBUG, ScopeInterface::SCOPE_STORE) + ->willReturn('1'); + + $result = $this->helper->getDebugStatus(); + $this->assertEquals('1', $result); + } + + public function testGetDebugStatusReturnsNullWhenDisabled() + { + // Mock the scopeConfig to return null when debug is disabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_DEBUG, ScopeInterface::SCOPE_STORE) + ->willReturn(null); + + $result = $this->helper->getDebugStatus(); + $this->assertNull($result); + } + + public function testGetExtensionVersion() + { + // Mock the moduleList to return a specific version + $this->moduleListMock->method('getOne') + ->with('BobGroup_BobGo') + ->willReturn(['setup_version' => '1.2.3']); + + $result = $this->helper->getExtensionVersion(); + $this->assertEquals('1.2.3', $result); + } + + public function testGetExtensionVersionReturnsNAWhenModuleNotFound() + { + // Mock the moduleList to return null (module not found) + $this->moduleListMock->method('getOne') + ->with('BobGroup_BobGo') + ->willReturn(null); + + $result = $this->helper->getExtensionVersion(); + $this->assertEquals('N/A', $result); + } + + public function testLogWithDebugEnabled() + { + // Mock the scopeConfig to return '1' when checking if debug is enabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_DEBUG, ScopeInterface::SCOPE_STORE) + ->willReturn('1'); + + // Expect the logger to be called with a specific message + $this->loggerMock->expects($this->once()) + ->method('debug') + ->with('Test message'); + + $this->helper->log('Test message'); + } + + public function testLogWithDebugDisabled() + { + // Mock the scopeConfig to return null when debug is disabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_DEBUG, ScopeInterface::SCOPE_STORE) + ->willReturn(null); + + // Expect the logger not to be called + $this->loggerMock->expects($this->never()) + ->method('debug'); + + $this->helper->log('Test message'); + } + + public function testLogWithSeparator() + { + // Mock the scopeConfig to return '1' when checking if debug is enabled + $this->scopeConfigMock->method('getValue') + ->with(Data::XML_PATH_DEBUG, ScopeInterface::SCOPE_STORE) + ->willReturn('1'); + + // Expect the logger to be called with a separator and the message + $this->loggerMock->expects($this->exactly(2)) + ->method('debug') + ->withConsecutive( + [str_repeat('=', 100)], + ['Test message'] + ); + + $this->helper->log('Test message', true); + } +} diff --git a/Test/Unit/Model/Carrier/AdditionalInfoTest.php b/Test/Unit/Model/Carrier/AdditionalInfoTest.php new file mode 100644 index 0000000..c9a95b2 --- /dev/null +++ b/Test/Unit/Model/Carrier/AdditionalInfoTest.php @@ -0,0 +1,130 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Model\Carrier; + +use BobGroup\BobGo\Model\Carrier\AdditionalInfo; +use Magento\Framework\App\Request\Http; +use Magento\Directory\Model\CountryFactory; +use Magento\Directory\Model\Country; +use PHPUnit\Framework\TestCase; + +class AdditionalInfoTest extends TestCase +{ + private $additionalInfo; + private $requestMock; + private $countryFactoryMock; + private $countryMock; + + protected function setUp(): void + { + $this->requestMock = $this->createMock(Http::class); + $this->countryFactoryMock = $this->createMock(CountryFactory::class); + $this->countryMock = $this->createMock(Country::class); + + $this->countryFactoryMock->method('create') + ->willReturn($this->countryMock); + + $this->countryMock->method('loadByCode') + ->willReturn($this->countryMock); + + $this->additionalInfo = new AdditionalInfo($this->countryFactoryMock, $this->requestMock); + } + + public function testGetCountryName() + { + $countryId = 'US'; + + $this->countryMock->method('getName') + ->willReturn('United States'); + + $result = $this->additionalInfo->getCountryName($countryId); + + $this->assertEquals('United States', $result); + } + + public function testGetDestComp() + { + $requestBody = json_encode([ + 'address' => [ + 'company' => 'Test Company' + ] + ]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getDestComp(); + + $this->assertEquals('Test Company', $result); + } + + public function testGetDestCompReturnsEmptyStringWhenNotSet() + { + $requestBody = json_encode([]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getDestComp(); + + $this->assertEquals('', $result); + } + + public function testGetSuburb() + { + $requestBody = json_encode([ + 'address' => [ + 'custom_attributes' => [ + ['value' => 'Test Suburb'] + ] + ] + ]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getSuburb(); + + $this->assertEquals('Test Suburb', $result); + } + + public function testGetSuburbReturnsEmptyStringWhenNotSet() + { + $requestBody = json_encode([]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getSuburb(); + + $this->assertEquals('', $result); + } + + public function testGetDestTelephone() + { + $requestBody = json_encode([ + 'address' => [ + 'telephone' => '123456789' + ] + ]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getDestTelephone(); + + $this->assertEquals('123456789', $result); + } + + public function testGetDestTelephoneReturnsEmptyStringWhenNotSet() + { + $requestBody = json_encode([]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->additionalInfo->getDestTelephone(); + + $this->assertEquals('', $result); + } +} diff --git a/Test/Unit/Model/Carrier/BobGoTest.php b/Test/Unit/Model/Carrier/BobGoTest.php new file mode 100644 index 0000000..e18a792 --- /dev/null +++ b/Test/Unit/Model/Carrier/BobGoTest.php @@ -0,0 +1,194 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Model\Carrier; + +use BobGroup\BobGo\Model\Carrier\BobGo; +use BobGroup\BobGo\Model\Carrier\AdditionalInfo; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogInventory\Api\StockRegistryInterface; +use Magento\Directory\Helper\Data; +use Magento\Directory\Model\CountryFactory; +use Magento\Directory\Model\CurrencyFactory; +use Magento\Directory\Model\RegionFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Request\Http as MagentoHttp; +use Magento\Framework\Controller\Result\JsonFactory; +use Magento\Framework\DataObject; +use Magento\Framework\HTTP\Client\Curl; +use Magento\Framework\HTTP\Client\CurlFactory; +use Magento\Framework\Xml\Security; +use Magento\Quote\Model\Quote\Address\RateRequest; +use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory; +use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; +use Magento\Shipping\Model\Rate\ResultFactory; +use Magento\Shipping\Model\Tracking\Result\StatusFactory; +use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class BobGoTest extends TestCase +{ + private $bobGo; + private $storeManagerMock; + private $scopeConfigMock; + private $curlMock; + private $resultFactoryMock; + private $methodFactoryMock; + private $additionalInfoMock; + + protected function setUp(): void + { + // Create mock objects for all dependencies + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $this->curlMock = $this->createMock(Curl::class); // Ensure Curl mock is initialized + $this->resultFactoryMock = $this->createMock(ResultFactory::class); + $this->methodFactoryMock = $this->createMock(MethodFactory::class); + $this->additionalInfoMock = $this->createMock(AdditionalInfo::class); // Correctly mock AdditionalInfo + + // Create mock objects for other dependencies that aren't used directly + $jsonFactoryMock = $this->createMock(JsonFactory::class); + $rateErrorFactoryMock = $this->createMock(ErrorFactory::class); + $loggerMock = $this->createMock(LoggerInterface::class); + $xmlSecurityMock = $this->createMock(Security::class); + $xmlElFactoryMock = $this->createMock(\Magento\Shipping\Model\Simplexml\ElementFactory::class); + $trackFactoryMock = $this->createMock(\Magento\Shipping\Model\Tracking\ResultFactory::class); + $trackErrorFactoryMock = $this->createMock(\Magento\Shipping\Model\Tracking\Result\ErrorFactory::class); + $trackStatusFactoryMock = $this->createMock(StatusFactory::class); + $regionFactoryMock = $this->createMock(RegionFactory::class); + $countryFactoryMock = $this->createMock(CountryFactory::class); + $currencyFactoryMock = $this->createMock(CurrencyFactory::class); + $directoryDataMock = $this->createMock(Data::class); + $stockRegistryMock = $this->createMock(StockRegistryInterface::class); + $productCollectionFactoryMock = $this->createMock(CollectionFactory::class); + + // Mock the CurlFactory to return the Curl mock + $curlFactoryMock = $this->createMock(CurlFactory::class); + $curlFactoryMock->method('create')->willReturn($this->curlMock); + + $requestMock = $this->createMock(MagentoHttp::class); + + // Instantiate the BobGo class with the mocked dependencies + $this->bobGo = new BobGo( + $this->scopeConfigMock, + $rateErrorFactoryMock, + $loggerMock, + $xmlSecurityMock, + $xmlElFactoryMock, + $this->resultFactoryMock, + $this->methodFactoryMock, + $trackFactoryMock, + $trackErrorFactoryMock, + $trackStatusFactoryMock, + $regionFactoryMock, + $countryFactoryMock, + $currencyFactoryMock, + $directoryDataMock, + $stockRegistryMock, + $this->storeManagerMock, + $productCollectionFactoryMock, + $jsonFactoryMock, + $curlFactoryMock, // Pass the CurlFactory mock here + $requestMock, + [] + ); + + // Assign the mocked AdditionalInfo directly to the BobGo instance + $this->bobGo->additionalInfo = $this->additionalInfoMock; + } + + +// Your test methods go here... + +public function testGetBaseUrl() + { + $storeMock = $this->createMock(\Magento\Store\Model\Store::class); + $this->storeManagerMock->method('getStore')->willReturn($storeMock); + $storeMock->method('getBaseUrl')->willReturn('https://www.example.com/'); + + $baseUrl = $this->bobGo->getBaseUrl(); + + $this->assertEquals('example.com', $baseUrl); + } + + public function testGetDestComp() + { + $this->additionalInfoMock->method('getDestComp')->willReturn('Test Company'); + + $destComp = $this->bobGo->getDestComp(); + + $this->assertEquals('Test Company', $destComp); + } + + public function testGetDestSuburb() + { + $this->additionalInfoMock->method('getSuburb')->willReturn('Test Suburb'); + + $destSuburb = $this->bobGo->getDestSuburb(); + + $this->assertEquals('Test Suburb', $destSuburb); + } + + public function testGetRates() + { + $payload = [ + 'identifier' => 'example.com', + 'rate' => [ + 'origin' => [ + 'company' => 'Test Company', + 'address1' => '123 Test St', + 'city' => 'Test City', + 'country_code' => 'US', + 'postal_code' => '12345', + ], + 'destination' => [ + 'company' => 'Destination Company', + 'address1' => '456 Destination St', + 'city' => 'Destination City', + 'country_code' => 'ZA', + 'postal_code' => '67890', + ], + 'items' => [ + [ + 'sku' => 'item-1', + 'quantity' => 1, + 'price' => 100.00, + 'weight' => 500, + ], + ], + ], + ]; + + $this->curlMock->method('getBody')->willReturn(json_encode(['rates' => [['id' => 'rate-1']]])); + + $rates = $this->bobGo->getRates($payload); + + $this->assertIsArray($rates); + $this->assertEquals('rate-1', $rates['rates'][0]['id']); + } + + public function testProcessAdditionalValidation() + { + // Create a mock for Product + $productMock = $this->createMock(\Magento\Catalog\Model\Product::class); + $productMock->method('isVirtual')->willReturn(false); + $productMock->method('getWeight')->willReturn(1); + + // Create a mock for Quote Item + $quoteItemMock = $this->createMock(\Magento\Quote\Model\Quote\Item::class); + $quoteItemMock->method('getProduct')->willReturn($productMock); + + // Create a real RateRequest object + $rateRequest = new RateRequest(); + $rateRequest->setDestPostcode('12345'); + $rateRequest->setDestCountryId('ZA'); + $rateRequest->setAllItems([$quoteItemMock]); + + $result = $this->bobGo->processAdditionalValidation($rateRequest); + + $this->assertInstanceOf(BobGo::class, $result); + } + + +} diff --git a/Test/Unit/Model/Carrier/USubsTest.php b/Test/Unit/Model/Carrier/USubsTest.php new file mode 100644 index 0000000..e1c1f06 --- /dev/null +++ b/Test/Unit/Model/Carrier/USubsTest.php @@ -0,0 +1,70 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Model\Carrier; + +use BobGroup\BobGo\Model\Carrier\USubs; +use Magento\Framework\App\Request\Http; +use PHPUnit\Framework\TestCase; + +class USubsTest extends TestCase +{ + /** + * @var USubs + */ + private $uSubs; + + /** + * @var Http|\PHPUnit\Framework\MockObject\MockObject + */ + private $requestMock; + + protected function setUp(): void + { + $this->requestMock = $this->createMock(Http::class); + + $this->uSubs = new USubs($this->requestMock); + } + + public function testGetDestComp() + { + $requestBody = json_encode([ + 'address' => [ + 'company' => 'Test Company' + ] + ]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->uSubs->getDestComp(); + + $this->assertEquals('Test Company', $result); + } + + public function testGetDestCompReturnsEmptyStringWhenNotSet() + { + $requestBody = json_encode([]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->uSubs->getDestComp(); + + $this->assertEquals('', $result); + } + + public function testGetDestCompReturnsEmptyStringWhenInvalidStructure() + { + // Test case where the JSON structure is invalid + $requestBody = json_encode([ + 'invalid' => 'structure' + ]); + + $this->requestMock->method('getContent') + ->willReturn($requestBody); + + $result = $this->uSubs->getDestComp(); + + $this->assertEquals('', $result); + } +} diff --git a/Test/Unit/Model/Source/FreemethodTest.php b/Test/Unit/Model/Source/FreemethodTest.php new file mode 100644 index 0000000..7b70d11 --- /dev/null +++ b/Test/Unit/Model/Source/FreemethodTest.php @@ -0,0 +1,42 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Model\Source; + +use BobGroup\BobGo\Model\Carrier\BobGo; +use BobGroup\BobGo\Model\Source\Freemethod; +use PHPUnit\Framework\TestCase; + +class FreemethodTest extends TestCase +{ + /** + * @var Freemethod + */ + private $freemethod; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $bobGoMock; + + protected function setUp(): void + { + // Mock the BobGo dependency required by the parent class + $this->bobGoMock = $this->createMock(BobGo::class); + + // Instantiate the Freemethod class with the required constructor arguments + $this->freemethod = new Freemethod($this->bobGoMock); + } + + public function testToOptionArray() + { + // Call the method under test + $result = $this->freemethod->toOptionArray(); + + // Check that the first option is 'None' + $this->assertArrayHasKey(0, $result); + $this->assertEquals(['value' => '', 'label' => 'None'], $result[0]); + + // Ensure the array is not empty after adding the 'None' option + $this->assertNotEmpty($result); + } +} diff --git a/Test/Unit/Model/Source/GenericTest.php b/Test/Unit/Model/Source/GenericTest.php new file mode 100644 index 0000000..b9e0cfa --- /dev/null +++ b/Test/Unit/Model/Source/GenericTest.php @@ -0,0 +1,67 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Model\Source; + +use BobGroup\BobGo\Model\Carrier\BobGo; +use BobGroup\BobGo\Model\Source\Generic; +use PHPUnit\Framework\TestCase; + +class GenericTest extends TestCase +{ + /** + * @var Generic + */ + private $generic; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $bobGoMock; + + protected function setUp(): void + { + // Mock the BobGo class dependency + $this->bobGoMock = $this->createMock(BobGo::class); + + // Instantiate the Generic class with the required constructor arguments + $this->generic = new Generic($this->bobGoMock); + + // Set the carrier code for the test + $reflection = new \ReflectionClass($this->generic); + $codeProperty = $reflection->getProperty('_code'); + $codeProperty->setAccessible(true); + $codeProperty->setValue($this->generic, 'test_code'); + } + + public function testToOptionArray() + { + // Set up the expected return value from the BobGo's getCode method + $this->bobGoMock->method('getCode')->with('test_code')->willReturn([ + 'code1' => 'Title 1', + 'code2' => 'Title 2', + ]); + + // Call the method under test + $result = $this->generic->toOptionArray(); + + // The expected result + $expected = [ + ['value' => 'code1', 'label' => 'Title 1'], + ['value' => 'code2', 'label' => 'Title 2'], + ]; + + $this->assertEquals($expected, $result); + } + + public function testToOptionArrayWithEmptyConfig() + { + // Set up the getCode method to return null + $this->bobGoMock->method('getCode')->with('test_code')->willReturn(null); + + // Call the method under test + $result = $this->generic->toOptionArray(); + + // The expected result is an empty array + $this->assertEquals([], $result); + } +} diff --git a/Test/Unit/Observer/ConfigChangeObserverTest.php b/Test/Unit/Observer/ConfigChangeObserverTest.php new file mode 100644 index 0000000..2838be8 --- /dev/null +++ b/Test/Unit/Observer/ConfigChangeObserverTest.php @@ -0,0 +1,117 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Observer; + +use BobGroup\BobGo\Model\Carrier\BobGo; +use BobGroup\BobGo\Observer\ConfigChangeObserver; +use Magento\Framework\Event\Observer; +use Magento\Framework\Message\ManagerInterface; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class ConfigChangeObserverTest extends TestCase +{ + /** + * @var ConfigChangeObserver + */ + private $observer; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $bobGoMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $loggerMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $messageManagerMock; + + protected function setUp(): void + { + // Mock the dependencies + $this->bobGoMock = $this->createMock(BobGo::class); + $this->loggerMock = $this->createMock(LoggerInterface::class); + $this->messageManagerMock = $this->createMock(ManagerInterface::class); + + // Instantiate the ConfigChangeObserver with the mocked dependencies + $this->observer = new ConfigChangeObserver( + $this->bobGoMock, + $this->loggerMock, + $this->messageManagerMock + ); + } + + public function testExecuteWithActiveCarrierAndSuccessfulConnection() + { + // Set up the observer mock + $observerMock = $this->createMock(Observer::class); + + // Mock the event data to simulate the carrier being active + $observerMock->method('getEvent')->willReturnSelf(); + $observerMock->method('getData')->with('changed_paths')->willReturn(['carriers/bobgo/active']); + + // Mock the BobGo object methods + $this->bobGoMock->method('isActive')->willReturn(true); + $this->bobGoMock->method('triggerRatesTest')->willReturn(true); + + // Expect success message to be added + $this->messageManagerMock->expects($this->once()) + ->method('addSuccessMessage') + ->with(__('Bob Go rates at checkout connected.')); + + // Execute the observer + $this->observer->execute($observerMock); + } + + public function testExecuteWithActiveCarrierAndFailedConnection() + { + // Set up the observer mock + $observerMock = $this->createMock(Observer::class); + + // Mock the event data to simulate the carrier being active + $observerMock->method('getEvent')->willReturnSelf(); + $observerMock->method('getData')->with('changed_paths')->willReturn(['carriers/bobgo/active']); + + // Mock the BobGo object methods + $this->bobGoMock->method('isActive')->willReturn(true); + $this->bobGoMock->method('triggerRatesTest')->willReturn(false); + + // Expect error message to be added + $this->messageManagerMock->expects($this->once()) + ->method('addErrorMessage') + ->with(__('Failed to connect to rates at checkout. Please check your internet connection + and make sure Rates at checkout is enabled for your channel on Bob Go. Please visit Bob Go + settings page to make sure your Magento channel is enabled to receive rates. + https://my.bobgo.co.za/rates-at-checkout?tab=settings')); + + // Execute the observer + $this->observer->execute($observerMock); + } + + public function testExecuteWithInactiveCarrier() + { + // Set up the observer mock + $observerMock = $this->createMock(Observer::class); + + // Mock the event data to simulate the carrier being inactive + $observerMock->method('getEvent')->willReturnSelf(); + $observerMock->method('getData')->with('changed_paths')->willReturn(['carriers/bobgo/active']); + + // Mock the BobGo object method to return inactive + $this->bobGoMock->method('isActive')->willReturn(false); + + // Ensure no messages are added + $this->messageManagerMock->expects($this->never()) + ->method('addSuccessMessage'); + $this->messageManagerMock->expects($this->never()) + ->method('addErrorMessage'); + + // Execute the observer + $this->observer->execute($observerMock); + } +} diff --git a/Test/Unit/Plugin/AddWeightUnitToOrderPluginTest.php b/Test/Unit/Plugin/AddWeightUnitToOrderPluginTest.php new file mode 100644 index 0000000..6dc3e80 --- /dev/null +++ b/Test/Unit/Plugin/AddWeightUnitToOrderPluginTest.php @@ -0,0 +1,97 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Plugin; + +use BobGroup\BobGo\Plugin\AddWeightUnitToOrderPlugin; +use Magento\Sales\Api\Data\OrderInterface; +use Magento\Sales\Api\Data\OrderItemInterface; +use Magento\Sales\Api\OrderRepositoryInterface; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; + +class AddWeightUnitToOrderPluginTest extends TestCase +{ + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $loggerMock; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $scopeConfigMock; + + /** + * @var AddWeightUnitToOrderPlugin + */ + private $plugin; + + protected function setUp(): void + { + $this->loggerMock = $this->createMock(LoggerInterface::class); + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + + // Instantiate the plugin + $this->plugin = new AddWeightUnitToOrderPlugin( + $this->loggerMock, + $this->scopeConfigMock + ); + } + + public function testBeforeSaveWithLbsWeightUnit() + { + // Mock the OrderInterface + $orderMock = $this->createMock(OrderInterface::class); + + // Mock the OrderItemInterface + $orderItemMock = $this->createMock(OrderItemInterface::class); + $orderItemMock->method('getWeight')->willReturn(10); // Assume 10 lbs + + // Return a list of order items + $orderMock->method('getItems')->willReturn([$orderItemMock]); + + // Set up the ScopeConfig mock to return 'lbs' + $this->scopeConfigMock->method('getValue') + ->with('general/locale/weight_unit', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn('lbs'); + + // Expect that the weight will be converted and set back + $orderItemMock->expects($this->once()) + ->method('setWeight') + ->with(4.5359237); // 10 lbs * 0.45359237 = 4.5359237 kg + + // Call the plugin's beforeSave method + $result = $this->plugin->beforeSave($this->createMock(OrderRepositoryInterface::class), $orderMock); + + // Assert that the returned order is the same as the original + $this->assertSame([$orderMock], $result); + } + + public function testBeforeSaveWithNonLbsWeightUnit() + { + // Mock the OrderInterface + $orderMock = $this->createMock(OrderInterface::class); + + // Mock the OrderItemInterface + $orderItemMock = $this->createMock(OrderItemInterface::class); + + // Return a list of order items + $orderMock->method('getItems')->willReturn([$orderItemMock]); + + // Set up the ScopeConfig mock to return 'kgs' + $this->scopeConfigMock->method('getValue') + ->with('general/locale/weight_unit', \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn('kgs'); + + // Expect that the setWeight method is never called since the unit is not 'lbs' + $orderItemMock->expects($this->never()) + ->method('setWeight'); + + // Call the plugin's beforeSave method + $result = $this->plugin->beforeSave($this->createMock(OrderRepositoryInterface::class), $orderMock); + + // Assert that the returned order is the same as the original + $this->assertSame([$orderMock], $result); + } +} diff --git a/Test/Unit/Plugin/Block/DataProviders/Tracking/ChangeTitleTest.php b/Test/Unit/Plugin/Block/DataProviders/Tracking/ChangeTitleTest.php new file mode 100644 index 0000000..6ee232d --- /dev/null +++ b/Test/Unit/Plugin/Block/DataProviders/Tracking/ChangeTitleTest.php @@ -0,0 +1,62 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Plugin\Block\DataProviders\Tracking; + +use BobGroup\BobGo\Plugin\Block\DataProviders\Tracking\ChangeTitle; +use BobGroup\BobGo\Model\Carrier\BobGo; +use Magento\Shipping\Model\Tracking\Result\Status; +use Magento\Shipping\Block\DataProviders\Tracking\DeliveryDateTitle as Subject; +use PHPUnit\Framework\TestCase; + +class ChangeTitleTest extends TestCase +{ + /** + * @var ChangeTitle + */ + private $plugin; + + protected function setUp(): void + { + // Instantiate the ChangeTitle plugin + $this->plugin = new ChangeTitle(); + } + + public function testAfterGetTitleWithBobGoCarrier() + { + // Create a custom Status object with BobGo carrier + $status = $this->getMockBuilder(Status::class) + ->setMethods(['getCarrier']) + ->getMock(); + + $status->method('getCarrier')->willReturn(BobGo::CODE); + + // Mock the Subject class + $subjectMock = $this->createMock(Subject::class); + + // Call the plugin method afterGetTitle + $result = $this->plugin->afterGetTitle($subjectMock, 'Original Title', $status); + + // Assert that the title was changed for BobGo carrier + $this->assertEquals('Expected delivery:', $result); + } + + public function testAfterGetTitleWithOtherCarrier() + { + // Create a custom Status object with a different carrier + $status = $this->getMockBuilder(Status::class) + ->setMethods(['getCarrier']) + ->getMock(); + + $status->method('getCarrier')->willReturn('other_carrier_code'); + + // Mock the Subject class + $subjectMock = $this->createMock(Subject::class); + + // Call the plugin method afterGetTitle + $originalTitle = 'Original Title'; + $result = $this->plugin->afterGetTitle($subjectMock, $originalTitle, $status); + + // Assert that the title was not changed for other carriers + $this->assertEquals($originalTitle, $result); + } +} diff --git a/Test/Unit/Plugin/Block/Tracking/PopUpDeliveryDateTest.php b/Test/Unit/Plugin/Block/Tracking/PopUpDeliveryDateTest.php new file mode 100644 index 0000000..4b04a20 --- /dev/null +++ b/Test/Unit/Plugin/Block/Tracking/PopUpDeliveryDateTest.php @@ -0,0 +1,80 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Plugin\Block\Tracking; + +use BobGroup\BobGo\Plugin\Block\Tracking\PopupDeliveryDate; +use Magento\Shipping\Block\Tracking\Popup; +use Magento\Shipping\Model\Tracking\Result\Status; +use PHPUnit\Framework\TestCase; + +class PopupDeliveryDateTest extends TestCase +{ + /** + * @var PopupDeliveryDate + */ + private $plugin; + + protected function setUp(): void + { + // Instantiate the PopupDeliveryDate plugin + $this->plugin = new PopupDeliveryDate(); + } + + public function testAfterFormatDeliveryDateTimeWithBobGoCarrier() + { + // Mock the Status class with BobGo carrier code + $statusMock = $this->createMock(Status::class); + $statusMock->method('getCarrier')->willReturn('bobgo_carrier_code'); + + // Mock the Popup class + $popupMock = $this->createMock(Popup::class); + $popupMock->method('getTrackingInfo')->willReturn([ + ['tracking_info' => $statusMock], + ]); + + // Mock the formatDeliveryDate method + $popupMock->method('formatDeliveryDate')->with('2024-08-19')->willReturn('Aug 19, 2024'); + + // Call the plugin method afterFormatDeliveryDateTime + $result = $this->plugin->afterFormatDeliveryDateTime($popupMock, 'Aug 19, 2024 10:00 AM', '2024-08-19', '10:00 AM'); + + // Assert that the time was stripped for BobGo carrier + $this->assertEquals('Aug 19, 2024', $result); + } + + public function testAfterFormatDeliveryDateTimeWithOtherCarrier() + { + // Mock the Status class with a different carrier code + $statusMock = $this->createMock(Status::class); + $statusMock->method('getCarrier')->willReturn('other_carrier_code'); + + // Mock the Popup class + $popupMock = $this->createMock(Popup::class); + $popupMock->method('getTrackingInfo')->willReturn([ + ['tracking_info' => $statusMock], + ]); + + // Call the plugin method afterFormatDeliveryDateTime + $result = $this->plugin->afterFormatDeliveryDateTime($popupMock, 'Aug 19, 2024 10:00 AM', '2024-08-19', '10:00 AM'); + + // Assert that the time remains unchanged for other carriers + $this->assertEquals('Aug 19, 2024 10:00 AM', $result); + } + + public function testGetCarrierWithNoTrackingInfo() + { + // Mock the Popup class with no tracking info + $popupMock = $this->createMock(Popup::class); + $popupMock->method('getTrackingInfo')->willReturn([]); + + // Call the getCarrier method directly + $reflection = new \ReflectionClass($this->plugin); + $method = $reflection->getMethod('getCarrier'); + $method->setAccessible(true); + + $result = $method->invokeArgs($this->plugin, [$popupMock]); + + // Assert that an empty string is returned when no tracking info is available + $this->assertEquals('', $result); + } +} diff --git a/Test/Unit/Plugin/Checkout/Block/LayoutProcessorPluginTest.php b/Test/Unit/Plugin/Checkout/Block/LayoutProcessorPluginTest.php new file mode 100644 index 0000000..9799548 --- /dev/null +++ b/Test/Unit/Plugin/Checkout/Block/LayoutProcessorPluginTest.php @@ -0,0 +1,85 @@ +<?php + +namespace BobGroup\BobGo\Test\Unit\Plugin\Checkout\Block; + +use BobGroup\BobGo\Plugin\Checkout\Block\LayoutProcessorPlugin; +use Magento\Checkout\Block\Checkout\LayoutProcessor; +use PHPUnit\Framework\TestCase; + +class LayoutProcessorPluginTest extends TestCase +{ + /** + * @var LayoutProcessorPlugin + */ + private $plugin; + + /** + * @var \PHPUnit\Framework\MockObject\MockObject + */ + private $layoutProcessorMock; + + protected function setUp(): void + { + // Instantiate the LayoutProcessorPlugin + $this->plugin = new LayoutProcessorPlugin(); + + // Mock the LayoutProcessor class + $this->layoutProcessorMock = $this->createMock(LayoutProcessor::class); + } + + public function testAfterProcessWithValidJsLayout() + { + // Mock the jsLayout array with the necessary structure + $jsLayout = [ + 'components' => [ + 'checkout' => [ + 'children' => [ + 'steps' => [ + 'children' => [ + 'shipping-step' => [ + 'children' => [ + 'shippingAddress' => [ + 'children' => [ + 'shipping-address-fieldset' => [ + 'children' => [] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ]; + + // Call the plugin's afterProcess method + $result = $this->plugin->afterProcess($this->layoutProcessorMock, $jsLayout); + + // Assert that the suburb field has been added to the jsLayout + $this->assertArrayHasKey('suburb', $result['components']['checkout']['children']['steps']['children'] + ['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children']); + + $suburbField = $result['components']['checkout']['children']['steps']['children']['shipping-step']['children'] + ['shippingAddress']['children']['shipping-address-fieldset']['children']['suburb']; + + $this->assertEquals('Suburb', $suburbField['label']); + $this->assertEquals(true, $suburbField['visible']); + $this->assertEquals('shippingAddress.custom_attributes.suburb', $suburbField['dataScope']); + } + + public function testAfterProcessWithInvalidJsLayout() + { + // Mock the jsLayout array with an incomplete structure + $jsLayout = [ + 'components' => [] + ]; + + // Call the plugin's afterProcess method + $result = $this->plugin->afterProcess($this->layoutProcessorMock, $jsLayout); + + // Assert that the jsLayout remains unchanged + $this->assertEquals($jsLayout, $result); + } +} -- GitLab