diff --git a/CHANGELOG.md b/CHANGELOG.md index cf955988..2e3dca40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,37 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [Unreleased](https://github.com/packlink-dev/ecommerce_module_core/compare/master...dev) +### Added + +- `isRegistered` method in `RepositoryRegistry`. +- `isShipmentLabelsAvailable` method in `OrderService` + +### Removed + +- `OrderService::updateShipmentLabel` method. +- `OrderRepository::isLabelSet` method. +- `OrderRepository::setLabelsByReference` method. + +### Changed +**NON-BREAKING CHANGES** +- `SendDraftTask` is now idempotent. +- `ShippingMethodConfiguration` DTO and `ShippingMethod` model are modified to enable setting list of allowed +destination countries for a shipping method. +- `UpdateShipmentDataTask` checks for update with different frequencies for orders with different statuses. +*NOTICE* For existing users delete old scheduled `UpdateShipmentDataTasks` and schedule new ones in the same manner as +they are scheduled in core. +- `AbstractGenericStudentRepositoryTest` extended to cover every ORM operator. + +**BREAKING CHANGES** + +- The lowest boundary in fixed price can be higher than zero. *NOTICE* Each integration for from input field must +remove "disabled" directive in template file as disabling from input field is now handled by js library. +- Advanced serialization mechanism has been implemented.`NativeSerializer` and `JsonSerializer` have been introduced. +This is a *breaking* change and each integration should register preferred serializer in bootstrap. +- `OrderRepository` introduced new method `getOrderReferencesWithStatus`. This method must be implemented in each +integration. +- Removed `OrderRepository::setLabelsByReference` method. + ## [v1.4.1](https://github.com/packlink-dev/ecommerce_module_core/compare/v1.4.1...1.4.0) - 2019-10-14 ### Added - `DraftController` is added to decrease the code in integrations related to creation of the draft diff --git a/src/BusinessLogic/BootstrapComponent.php b/src/BusinessLogic/BootstrapComponent.php index 0a2d25f8..d4e582c9 100644 --- a/src/BusinessLogic/BootstrapComponent.php +++ b/src/BusinessLogic/BootstrapComponent.php @@ -11,6 +11,7 @@ use Packlink\BusinessLogic\Http\Proxy; use Packlink\BusinessLogic\Location\LocationService; use Packlink\BusinessLogic\Order\OrderService; +use Packlink\BusinessLogic\OrderShipmentDetails\OrderShipmentDetailsService; use Packlink\BusinessLogic\Scheduler\ScheduleTickHandler; use Packlink\BusinessLogic\ShippingMethod\PackageTransformer; use Packlink\BusinessLogic\ShippingMethod\ShippingMethodService; @@ -90,6 +91,13 @@ function () { return PackageTransformer::getInstance(); } ); + + ServiceRegister::registerService( + OrderShipmentDetailsService::CLASS_NAME, + function () { + return OrderShipmentDetailsService::getInstance(); + } + ); } /** diff --git a/src/BusinessLogic/Controllers/DTO/ShippingMethodConfiguration.php b/src/BusinessLogic/Controllers/DTO/ShippingMethodConfiguration.php index 9be8527d..4c42227d 100644 --- a/src/BusinessLogic/Controllers/DTO/ShippingMethodConfiguration.php +++ b/src/BusinessLogic/Controllers/DTO/ShippingMethodConfiguration.php @@ -62,6 +62,18 @@ class ShippingMethodConfiguration extends BaseDto * @var mixed */ public $taxClass; + /** + * Flag that denotes whether is shipping to all countries allowed. + * + * @var boolean + */ + public $isShipToAllCountries = true; + /** + * If `isShipToAllCountries` set to FALSe than this array contains list of countries where shipping is allowed. + * + * @var array + */ + public $shippingCountries = array(); /** * Transforms DTO to its array format suitable for http client. @@ -76,6 +88,8 @@ public function toArray() 'pricePolicy' => $this->pricePolicy, 'showLogo' => $this->showLogo, 'taxClass' => $this->taxClass, + 'isShipToAllCountries' => $this->isShipToAllCountries, + 'shippingCountries' => $this->shippingCountries, ); if ($this->pricePolicy === ShippingMethod::PRICING_POLICY_PERCENT && $this->percentPricePolicy) { @@ -115,6 +129,18 @@ public static function fromArray(array $raw) $result->taxClass = isset($raw['taxClass']) ? $raw['taxClass'] : null; + if (isset($raw['isShipToAllCountries']) && is_bool($raw['isShipToAllCountries'])) { + $result->isShipToAllCountries = $raw['isShipToAllCountries']; + } else { + $result->isShipToAllCountries = true; + } + + if (isset($raw['shippingCountries']) && is_array($raw['shippingCountries'])) { + $result->shippingCountries = $raw['shippingCountries']; + } else { + $result->shippingCountries = array(); + } + if ($result->pricePolicy === ShippingMethod::PRICING_POLICY_PERCENT) { $value = $raw['percentPricePolicy']; $result->percentPricePolicy = PercentPricePolicy::fromArray($value); diff --git a/src/BusinessLogic/Controllers/ShippingMethodController.php b/src/BusinessLogic/Controllers/ShippingMethodController.php index e2ef2bea..d0087b91 100644 --- a/src/BusinessLogic/Controllers/ShippingMethodController.php +++ b/src/BusinessLogic/Controllers/ShippingMethodController.php @@ -12,7 +12,7 @@ /** * Class ShippingMethodController. * - * @package Packlink\BusinessLogic\Controllers + * @package Packlink\PacklinkPro\IntegrationCore\BusinessLogic\Controllers */ class ShippingMethodController { @@ -176,6 +176,8 @@ private function transformShippingMethodModelToDto(ShippingMethod $item) $shippingMethod->parcelDestination = $item->isDestinationDropOff() ? static::DROP_OFF : static::HOME; $shippingMethod->parcelOrigin = $item->isDepartureDropOff() ? static::DROP_OFF : static::PICKUP; $shippingMethod->taxClass = $item->getTaxClass(); + $shippingMethod->shippingCountries = $item->getShippingCountries(); + $shippingMethod->isShipToAllCountries = $item->isShipToAllCountries(); $shippingMethod->pricePolicy = $item->getPricingPolicy(); $shippingMethod->percentPricePolicy = $item->getPercentPricePolicy(); @@ -214,6 +216,8 @@ private function updateModelData(ShippingMethodConfiguration $configuration, Shi $model->setTitle($configuration->name); $model->setDisplayLogo($configuration->showLogo); $model->setTaxClass($configuration->taxClass); + $model->setShipToAllCountries($configuration->isShipToAllCountries); + $model->setShippingCountries($configuration->shippingCountries); switch ($configuration->pricePolicy) { case ShippingMethod::PRICING_POLICY_PACKLINK: $model->setPacklinkPricePolicy(); diff --git a/src/BusinessLogic/Order/Interfaces/OrderRepository.php b/src/BusinessLogic/Order/Interfaces/OrderRepository.php index 68ff6a88..0d63bc93 100644 --- a/src/BusinessLogic/Order/Interfaces/OrderRepository.php +++ b/src/BusinessLogic/Order/Interfaces/OrderRepository.php @@ -25,6 +25,15 @@ interface OrderRepository */ public function getIncompleteOrderReferences(); + /** + * Retrieves list of order references where order is in one of the provided statuses. + * + * @param array $statuses List of order statuses. + * + * @return string[] Array of shipment references. + */ + public function getOrderReferencesWithStatus(array $statuses); + /** * Fetches and returns system order by its unique identifier. * @@ -46,16 +55,6 @@ public function getOrderAndShippingData($orderId); */ public function setReference($orderId, $shipmentReference); - /** - * Sets order packlink shipping labels to an order by shipment reference. - * - * @param string $shipmentReference Packlink shipment reference. - * @param string[] $labels Packlink shipping labels. - * - * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound When order with provided reference is not found. - */ - public function setLabelsByReference($shipmentReference, array $labels); - /** * Sets order packlink shipment tracking history to an order for given shipment. * @@ -105,13 +104,4 @@ public function markShipmentDeleted($shipmentReference); * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound When order with provided reference is not found. */ public function isShipmentDeleted($shipmentReference); - - /** - * Returns whether shipment identified by provided reference has Packlink shipment label set. - * - * @param string $shipmentReference Packlink shipment reference. - * - * @return bool Returns TRUE if label is set; otherwise, FALSE. - */ - public function isLabelSet($shipmentReference); } diff --git a/src/BusinessLogic/Order/Models/OrderShipmentDetails.php b/src/BusinessLogic/Order/Models/OrderShipmentDetails.php index 8b0188e1..3f390a39 100644 --- a/src/BusinessLogic/Order/Models/OrderShipmentDetails.php +++ b/src/BusinessLogic/Order/Models/OrderShipmentDetails.php @@ -221,19 +221,11 @@ public function getShipmentLabels() /** * Sets order shipment labels from array of links to PDF. * - * @param array $links Array of links to PDF. + * @param ShipmentLabel[] Array of links to PDF. */ - public function setShipmentLabels(array $links) + public function setShipmentLabels(array $labels) { - if (empty($this->shipmentLabels)) { - $shipmentLabels = array(); - - foreach ($links as $link) { - $shipmentLabels[] = new ShipmentLabel($link); - } - - $this->shipmentLabels = $shipmentLabels; - } + $this->shipmentLabels = $labels; } /** diff --git a/src/BusinessLogic/Order/OrderService.php b/src/BusinessLogic/Order/OrderService.php index d1e235fe..d27dd8d5 100644 --- a/src/BusinessLogic/Order/OrderService.php +++ b/src/BusinessLogic/Order/OrderService.php @@ -10,6 +10,7 @@ use Packlink\BusinessLogic\Http\DTO\Draft; use Packlink\BusinessLogic\Http\DTO\Package; use Packlink\BusinessLogic\Http\DTO\Shipment; +use Packlink\BusinessLogic\Http\DTO\ShipmentLabel; use Packlink\BusinessLogic\Http\Proxy; use Packlink\BusinessLogic\Order\Exceptions\OrderNotFound; use Packlink\BusinessLogic\Order\Interfaces\OrderRepository; @@ -87,35 +88,6 @@ public function setReference($orderId, $shipmentReference) $this->orderRepository->setReference($orderId, $shipmentReference); } - /** - * Updates shipment label from API for order with given shipment reference. - * - * @param Shipment $shipment Shipment DTO for given reference number. - */ - public function updateShipmentLabel(Shipment $shipment) - { - $referenceId = $shipment->reference; - if (!ShipmentStatus::shouldFetchLabels($shipment->status) - || $this->orderRepository->isLabelSet($referenceId) - ) { - return; - } - - /** @var Proxy $proxy */ - $proxy = ServiceRegister::getService(Proxy::CLASS_NAME); - $labels = array(); - try { - $labels = $proxy->getLabels($referenceId); - if (count($labels) > 0) { - $this->orderRepository->setLabelsByReference($referenceId, $labels); - } - } catch (HttpBaseException $e) { - Logger::logError($e->getMessage(), 'Core', array('referenceId' => $referenceId)); - } catch (OrderNotFound $e) { - Logger::logInfo($e->getMessage(), 'Core', array('referenceId' => $referenceId, 'labels' => $labels)); - } - } - /** * Updates shipping status from API for order with given shipment reference. * @@ -164,6 +136,52 @@ public function updateTrackingInfo(Shipment $shipment) } } + /** + * Retrieves list of order labels. + * + * @param string $reference Order reference. + * + * @return \Packlink\BusinessLogic\Http\DTO\ShipmentLabel[] List of shipment labels for an order defined by + * the provided reference. + */ + public function getShipmentLabels($reference) + { + /** @var Proxy $proxy */ + $proxy = ServiceRegister::getService(Proxy::CLASS_NAME); + $labels = array(); + + try { + $links = $proxy->getLabels($reference); + foreach ($links as $link) { + $labels[] = new ShipmentLabel($link); + } + } catch (\Exception $e) { + Logger::logError("Failed to retrieve labels for order [$reference] because: {$e->getMessage()}"); + } + + return $labels; + } + + /** + * Checks whether shipment labels are available. + * + * @param string $status + * + * @return bool TRUE if shipment labels are available; FALSE otherwise. + */ + public function isReadyToFetchShipmentLabels($status) + { + return in_array( + $status, + array( + ShipmentStatus::STATUS_READY, + ShipmentStatus::STATUS_IN_TRANSIT, + ShipmentStatus::STATUS_DELIVERED, + ), + true + ); + } + /** * Converts order object to draft DTO suitable for sending to Packlink. * diff --git a/src/BusinessLogic/OrderShipmentDetails/OrderShipmentDetailsService.php b/src/BusinessLogic/OrderShipmentDetails/OrderShipmentDetailsService.php new file mode 100644 index 00000000..7bf7e086 --- /dev/null +++ b/src/BusinessLogic/OrderShipmentDetails/OrderShipmentDetailsService.php @@ -0,0 +1,64 @@ +orderShipmentDetailsRepository = $this->getRepository(OrderShipmentDetails::getClassName()); + } + + /** + * Retrieves order shipment details. + * + * @param string | int $orderId Order id in an integration system. + * + * @return OrderShipmentDetails | null Instance that retrieved by the specifed id. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + */ + public function getDetailsByOrderId($orderId) + { + $query = new QueryFilter(); + $query->where('orderId', Operators::EQUALS, $orderId); + + /** @var OrderShipmentDetails | null $entity */ + $entity = $this->orderShipmentDetailsRepository->selectOne($query); + + return $entity; + } +} \ No newline at end of file diff --git a/src/BusinessLogic/Resources/js/CountrySelectorController.js b/src/BusinessLogic/Resources/js/CountrySelectorController.js new file mode 100644 index 00000000..e510fb18 --- /dev/null +++ b/src/BusinessLogic/Resources/js/CountrySelectorController.js @@ -0,0 +1,86 @@ +var Packlink = window.Packlink || {}; + +(function () { + /** + * Controller that displays shipping country selector pop up. + * + * @constructor + */ + function CountrySelectorController() { + let templateService = Packlink.templateService; + let extensionPoint = templateService.getComponent('pl-allowed-shipping-countries-ep'); + + this.display = display; + this.destroy = destroy; + + /** + * Displays country selector. + * + * @param {array} availableCountries List of available countries in system. + * @param {array} selectedCountries List of selected countries. + * @param {function} saveCallback callback when save button is clicked. + * @param {function} cancelCallback callback when cancel button is clicked. + */ + function display(availableCountries, selectedCountries, saveCallback, cancelCallback) { + templateService.setTemplate('pl-allowed-countries-modal-template', 'pl-allowed-shipping-countries-ep', true); + + let saveBtn = templateService.getComponent('pl-countries-selector-save-btn', extensionPoint); + saveBtn.addEventListener('click', onSaveButtonClicked); + + if (selectedCountries.length === 0) { + saveBtn.disabled = true; + } + + let closeBtn = templateService.getComponent('pl-close-modal-btn', extensionPoint); + closeBtn.addEventListener('click', onCancelClicked); + + let cancelBtn = templateService.getComponent('pl-countries-selector-cancel-btn'); + cancelBtn.addEventListener('click', onCancelClicked); + + let selector = templateService.getComponent('pl-countries-selector', extensionPoint); + + for (let country of availableCountries) { + let option = document.createElement('option'); + option.value = country.value; + option.innerHTML = country.label; + + if (selectedCountries.indexOf(country.value) !== -1) { + option.selected = true; + } + + selector.appendChild(option); + } + + selector.addEventListener('change', onChangeSelector); + + function onCancelClicked() { + cancelCallback(); + } + + function onSaveButtonClicked() { + if (selector.selectedOptions.length === 0) { + saveBtn.disabled = true; + } else { + let result = []; + for (let option of selector.selectedOptions) { + result.push(option.value); + } + + saveCallback(result); + } + } + + function onChangeSelector() { + saveBtn.disabled = selector.selectedOptions.length === 0; + } + } + + function destroy() { + while (extensionPoint.firstChild) { + extensionPoint.firstChild.remove(); + } + } + } + + Packlink.CountrySelectorController = CountrySelectorController; +})(); diff --git a/src/BusinessLogic/Resources/js/OrderStateMappingController.js b/src/BusinessLogic/Resources/js/OrderStateMappingController.js index 136901ef..091f257f 100644 --- a/src/BusinessLogic/Resources/js/OrderStateMappingController.js +++ b/src/BusinessLogic/Resources/js/OrderStateMappingController.js @@ -7,13 +7,7 @@ var Packlink = window.Packlink || {}; let ajaxService = Packlink.ajaxService; let state = Packlink.state; - const statuses = [ - 'pending', - 'processing', - 'readyForShipping', - 'inTransit', - 'delivered' - ]; + let statuses = []; let page; let mappings = {}; @@ -24,6 +18,11 @@ var Packlink = window.Packlink || {}; page = templateService.setTemplate('pl-order-state-mapping-template'); + let statusElements = templateService.getComponentsByAttribute('data-pl-status', page); + for (let statusElement of statusElements) { + statuses.push(statusElement.getAttribute('data-pl-status')); + } + attachEventHandlers(); ajaxService.get(configuration.getSystemOrderStatusesUrl, getSystemOrderStatusesSuccessHandler); diff --git a/src/BusinessLogic/Resources/js/ShippingMethodsController.js b/src/BusinessLogic/Resources/js/ShippingMethodsController.js index 64a680d5..764b923e 100644 --- a/src/BusinessLogic/Resources/js/ShippingMethodsController.js +++ b/src/BusinessLogic/Resources/js/ShippingMethodsController.js @@ -25,7 +25,7 @@ var Packlink = window.Packlink || {}; let currentNavTab = 'all'; let spinnerBarrierCount = 0; - let spinnerBarrier = configuration.hasTaxConfiguration ? 2 : 1; + let spinnerBarrier = getSpinnerBarrier(); /** @var {{parcelSet, warehouseSet, shippingMethodSet}} dashboardData */ let dashboardData = {}; @@ -33,7 +33,8 @@ var Packlink = window.Packlink || {}; /** * @var {{id, name, title, logoUrl, taxClass, deliveryDescription, showLogo, deliveryType, * parcelDestination, parcelOrigin, selected, - * pricePolicy, fixedPriceByWeightPolicy, fixedPriceByValuePolicy, percentPricePolicy}} methodModel + * pricePolicy, fixedPriceByWeightPolicy, fixedPriceByValuePolicy, percentPricePolicy, + * isShipToAllCountries, shippingCountries}} methodModel */ let methodModel = {}; let taxClasses = []; @@ -63,6 +64,9 @@ var Packlink = window.Packlink || {}; let autoConfigureInitialized = false; + let countrySelector = {}; + let availableCountries = []; + /** * Displays page content. */ @@ -121,6 +125,10 @@ var Packlink = window.Packlink || {}; ajaxService.get(configuration.getTaxClassesUrl, getTaxClassesSuccessHandler); } + if (configuration.hasCountryConfiguration) { + ajaxService.get(configuration.getShippingCountries, getShippingCountriesHandler); + } + ajaxService.get(configuration.getDashboardStatusUrl, function (response) { getStatusHandler(response); ajaxService.get(configuration.getMethodsStatusUrl, getShippingMethodsStatusHandler); @@ -144,7 +152,7 @@ var Packlink = window.Packlink || {}; } if (response.status === 'failed') { - hideDashboardModal(); + hideDashboardModal(true); showNoShippingMethodsMessage(); return; @@ -173,7 +181,7 @@ var Packlink = window.Packlink || {}; } if (response.length === 0) { - hideDashboardModal(); + hideDashboardModal(true); showNoShippingMethodsMessage(); return; @@ -723,6 +731,58 @@ var Packlink = window.Packlink || {}; let pricingPolicySelector = templateService.getComponent('pl-pricing-policy-selector', template); pricingPolicySelector.addEventListener('change', handleShippingMethodPricingPolicyChanged, true); pricingPolicySelector.value = methodModel.pricePolicy; + + if (configuration.hasCountryConfiguration) { + initializeCountryCountrySelector(methodModel, template); + } + } + + /** + * Initializes shipping country selector + * + * @param {object} method + * @param {Element} template + */ + function initializeCountryCountrySelector(method, template) { + let checkbox = templateService.getComponent('pl-country-selector-checkbox', template); + let countryListBtn = templateService.getComponent('pl-country-list-btn', template); + let countrySelectorCtrl = new Packlink.CountrySelectorController(); + + checkbox.addEventListener('change', onChangeCountrySelectorCheckbox); + countryListBtn.addEventListener('click', onClickCountryList); + + countrySelector.isShipToAllCountries = method.isShipToAllCountries; + countrySelector.shippingCountries = method.shippingCountries; + + checkbox.checked = countrySelector.isShipToAllCountries; + if (countrySelector.isShipToAllCountries) { + countryListBtn.classList.add('hidden'); + } + + function onChangeCountrySelectorCheckbox(event) { + countrySelector.isShipToAllCountries = event.target.checked; + + if (countrySelector.isShipToAllCountries) { + countryListBtn.classList.add('hidden'); + countrySelectorCtrl.destroy(); + } else { + countryListBtn.classList.remove('hidden'); + countrySelectorCtrl.display(availableCountries, countrySelector.shippingCountries, save, cancel); + } + } + + function onClickCountryList() { + countrySelectorCtrl.display(availableCountries, countrySelector.shippingCountries, save, cancel); + } + + function save(selectedCountries) { + countrySelector.shippingCountries = selectedCountries; + countrySelectorCtrl.destroy(); + } + + function cancel() { + countrySelectorCtrl.destroy(); + } } /** @@ -734,7 +794,7 @@ var Packlink = window.Packlink || {}; let scroller = templateService.getComponent('pl-table-scroll', extensionPoint); if (scroller) { - let rowIndex = renderedShippingMethods.indexOf(methodId); + let rowIndex = renderedShippingMethods.indexOf(methodId + ''); scroller.scrollTo({ smooth: true, left: 0, @@ -836,6 +896,18 @@ var Packlink = window.Packlink || {}; methodModel.taxClass = templateService.getComponent('pl-tax-selector', extensionPoint).value; } + if (configuration.hasCountryConfiguration) { + methodModel.isShipToAllCountries = countrySelector.isShipToAllCountries; + + if (!methodModel.isShipToAllCountries) { + methodModel.shippingCountries = countrySelector.shippingCountries; + } else { + methodModel.shippingCountries = []; + } + + countrySelector = {}; + } + ajaxService.post( configuration.saveUrl, methodModel, @@ -920,6 +992,14 @@ var Packlink = window.Packlink || {}; isValid = false; } + if (configuration.hasCountryConfiguration + && !countrySelector.isShipToAllCountries + && countrySelector.shippingCountries.length === 0) { + utilityService.showFlashMessage(Packlink.errorMsgs.invalidCountryList, 'danger'); + + isValid = false; + } + return isValid; } @@ -1089,6 +1169,16 @@ var Packlink = window.Packlink || {}; input.value = policy[field]; input.setAttribute('data-pl-' + field + '-id', id.toString()); + if (field === 'from') { + if (id === 0) { + input.addEventListener('blur', function (event) { + onFixedPriceFromBlur(event, byWeight); + }, true); + } else { + input.disabled = true; + } + } + if (field === 'to') { input.addEventListener( 'blur', @@ -1108,6 +1198,30 @@ var Packlink = window.Packlink || {}; } } + /** + * Handles on Fixed Price From input field blur event. + * + * @param event + * @param {boolean} byWeight + */ + function onFixedPriceFromBlur(event, byWeight) { + let policy = getFixedPricePolicy(byWeight); + let index = parseInt(event.target.getAttribute('data-pl-from-id')); + + if (index !== 0) { + return; + } + + let value = event.target.value; + let numericValue = parseFloat(value); + // noinspection EqualityComparisonWithCoercionJS + methodModel[policy][index].from = event.target.value == numericValue ? numericValue : value; + + templateService.removeError(event.target); + + displayFixedPricesSubForm(index === methodModel[policy].length - 1, false, false, false, byWeight) + } + /** * Handles blur event on to input field. * @@ -1260,7 +1374,7 @@ var Packlink = window.Packlink || {}; */ function isFixedPriceInputTypeValid(byWeight) { let policies = methodModel[getFixedPricePolicy(byWeight)]; - let fields = ['amount', 'to']; + let fields = ['from', 'amount', 'to']; let result = true; for (let i = 0; i < policies.length; i++) { @@ -1310,6 +1424,13 @@ var Packlink = window.Packlink || {}; for (let i = 0; i < policies.length; i++) { let current = policies[i]; let successor = policies.length < i + 1 ? policies[i + 1] : null; + + if (current.from < 0) { + let input = templateService.getComponent('data-pl-from-id', tableExtensionPoint, i); + templateService.setError(input, Packlink.errorMsgs.invalid); + result = false; + } + if (current.from >= current.to || (successor && successor.from && current.to > successor.from)) { let input = templateService.getComponent('data-pl-to-id', tableExtensionPoint, i); templateService.setError(input, Packlink.errorMsgs.invalid); @@ -1520,6 +1641,14 @@ var Packlink = window.Packlink || {}; } } + function getShippingCountriesHandler(response) { + availableCountries = response; + + if (spinnerBarrier === ++spinnerBarrierCount) { + utilityService.hideSpinner(); + } + } + /** * Checks whether tax class exists in system. * @@ -1665,9 +1794,15 @@ var Packlink = window.Packlink || {}; /** * Hides dashboard modal. + * + * @param {boolean} [isAutoconfigure] */ - function hideDashboardModal() { - if (!dashboardData.parcelSet || !dashboardData.warehouseSet) { + function hideDashboardModal(isAutoconfigure) { + if (typeof isAutoconfigure !== 'boolean') { + isAutoconfigure = false; + } + + if (!isAutoconfigure && (!dashboardData.parcelSet || !dashboardData.warehouseSet)) { return; } @@ -1678,6 +1813,16 @@ var Packlink = window.Packlink || {}; isDashboardShown = false; } + + /** + * Retrieves spinner barrier value. Spinner barrier is used to denote number of required ajax requests that + * have to be completed before initial loading spinner is hidden. + * + * @return {number} + */ + function getSpinnerBarrier() { + return 1 + !!(configuration.hasTaxConfiguration) + !!(configuration.hasCountryConfiguration); + } } Packlink.ShippingMethodsController = ShippingMethodsController; diff --git a/src/BusinessLogic/Resources/js/StateController.js b/src/BusinessLogic/Resources/js/StateController.js index 897105c7..17c44614 100644 --- a/src/BusinessLogic/Resources/js/StateController.js +++ b/src/BusinessLogic/Resources/js/StateController.js @@ -10,6 +10,7 @@ var Packlink = window.Packlink || {}; * pageConfiguration: array, * scrollConfiguration: {scrollOffset: number, rowHeight: number}, * hasTaxConfiguration: boolean, + * hasCountryConfiguration: boolean, * canDisplayCarrierLogos: boolean, * shippingServiceMaxTitleLength: number, * autoConfigureStartUrl: string, @@ -31,7 +32,8 @@ var Packlink = window.Packlink || {}; * shopShippingMethodsDisableUrl: string, * getSystemOrderStatusesUrl: string, * orderStatusMappingsSaveUrl: string, - * orderStatusMappingsGetUrl: string + * orderStatusMappingsGetUrl: string, + * getShippingCountriesUrl: string * }} configuration * * @constructor @@ -87,7 +89,9 @@ var Packlink = window.Packlink || {}; autoConfigureStartUrl: configuration.autoConfigureStartUrl, hasTaxConfiguration: configuration.hasTaxConfiguration, getTaxClassesUrl: configuration.shippingMethodsGetTaxClassesUrl, - canDisplayCarrierLogos: configuration.canDisplayCarrierLogos + canDisplayCarrierLogos: configuration.canDisplayCarrierLogos, + getShippingCountries: configuration.getShippingCountriesUrl, + hasCountryConfiguration: configuration.hasCountryConfiguration }, 'order-state-mapping': { getSystemOrderStatusesUrl: configuration.getSystemOrderStatusesUrl, diff --git a/src/BusinessLogic/Resources/js/TranslationMessages.js b/src/BusinessLogic/Resources/js/TranslationMessages.js index 3f09b1ee..de02ef05 100644 --- a/src/BusinessLogic/Resources/js/TranslationMessages.js +++ b/src/BusinessLogic/Resources/js/TranslationMessages.js @@ -8,7 +8,8 @@ Packlink.errorMsgs = { titleLength: 'Title can have at most 64 characters.', greaterThanZero: 'Value must be greater than 0.', numberOfDecimalPlaces: 'Field must have 2 decimal places.', - integer: 'Field must be an integer.' + integer: 'Field must be an integer.', + invalidCountryList: 'You must select destination countries.' }; Packlink.successMsgs = { diff --git a/src/BusinessLogic/Scheduler/Models/HourlySchedule.php b/src/BusinessLogic/Scheduler/Models/HourlySchedule.php index d70a2485..52c52342 100644 --- a/src/BusinessLogic/Scheduler/Models/HourlySchedule.php +++ b/src/BusinessLogic/Scheduler/Models/HourlySchedule.php @@ -21,6 +21,7 @@ class HourlySchedule extends Schedule */ protected $fields = array( 'id', + 'recurring', 'queueName', 'minute', 'hour', diff --git a/src/BusinessLogic/Scheduler/Models/Schedule.php b/src/BusinessLogic/Scheduler/Models/Schedule.php index d2dba48b..1b6d6ec2 100644 --- a/src/BusinessLogic/Scheduler/Models/Schedule.php +++ b/src/BusinessLogic/Scheduler/Models/Schedule.php @@ -5,6 +5,7 @@ use Logeecom\Infrastructure\ORM\Configuration\EntityConfiguration; use Logeecom\Infrastructure\ORM\Configuration\IndexMap; use Logeecom\Infrastructure\ORM\Entity; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Task; use Logeecom\Infrastructure\Utility\TimeProvider; @@ -105,7 +106,7 @@ public function inflate(array $data) { parent::inflate($data); - $this->task = unserialize($data['task']); + $this->task = Serializer::unserialize($data['task']); } /** @@ -116,7 +117,7 @@ public function inflate(array $data) public function toArray() { $data = parent::toArray(); - $data['task'] = serialize($this->task); + $data['task'] = Serializer::serialize($this->task); return $data; } diff --git a/src/BusinessLogic/Scheduler/ScheduleCheckTask.php b/src/BusinessLogic/Scheduler/ScheduleCheckTask.php index 16670349..55993636 100644 --- a/src/BusinessLogic/Scheduler/ScheduleCheckTask.php +++ b/src/BusinessLogic/Scheduler/ScheduleCheckTask.php @@ -5,6 +5,7 @@ use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\ORM\QueryFilter\QueryFilter; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Exceptions\QueueStorageUnavailableException; use Logeecom\Infrastructure\TaskExecution\QueueService; @@ -24,6 +25,29 @@ class ScheduleCheckTask extends Task */ private $repository; + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static(); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array(); + } + /** * Runs task logic. * @@ -53,7 +77,7 @@ public function execute() array( 'ExceptionMessage' => $ex->getMessage(), 'ExceptionTrace' => $ex->getTraceAsString(), - 'TaskData' => serialize($task), + 'TaskData' => Serializer::serialize($task), ) ); } diff --git a/src/BusinessLogic/Scheduler/ScheduleTickHandler.php b/src/BusinessLogic/Scheduler/ScheduleTickHandler.php index 8c3027b0..4ec6fad8 100644 --- a/src/BusinessLogic/Scheduler/ScheduleTickHandler.php +++ b/src/BusinessLogic/Scheduler/ScheduleTickHandler.php @@ -3,6 +3,7 @@ namespace Packlink\BusinessLogic\Scheduler; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Exceptions\QueueStorageUnavailableException; use Logeecom\Infrastructure\TaskExecution\QueueService; @@ -38,7 +39,7 @@ public function handle() array( 'ExceptionMessage' => $ex->getMessage(), 'ExceptionTrace' => $ex->getTraceAsString(), - 'TaskData' => serialize($task), + 'TaskData' => Serializer::serialize($task), ) ); } diff --git a/src/BusinessLogic/ShippingMethod/Exceptions/FixedPriceValueOutOfBoundsException.php b/src/BusinessLogic/ShippingMethod/Exceptions/FixedPriceValueOutOfBoundsException.php new file mode 100644 index 00000000..5c5544d8 --- /dev/null +++ b/src/BusinessLogic/ShippingMethod/Exceptions/FixedPriceValueOutOfBoundsException.php @@ -0,0 +1,14 @@ +isShipToAllCountries = $data['isShipToAllCountries']; + } else { + $this->isShipToAllCountries = true; + } + + if (isset($data['shippingCountries']) && is_array($data['shippingCountries'])) { + $this->shippingCountries = $data['shippingCountries']; + } else { + $this->shippingCountries = array(); + } + if (!$this->getPricingPolicy()) { $this->pricingPolicy = static::PRICING_POLICY_PACKLINK; } @@ -624,6 +650,45 @@ public function setTaxClass($taxClass) $this->taxClass = $taxClass; } + /** + * Sets list of allowed destination countries. + * + * @param array $shippingCountries List of allowed destination countries. + */ + public function setShippingCountries(array $shippingCountries) { + $this->shippingCountries = $shippingCountries; + } + + /** + * Retrieves list of allowed destination countries. + * + * @return array List of allowed destination countries. + */ + public function getShippingCountries() + { + return $this->shippingCountries; + } + + /** + * Retrieves flag that denotes whether shipping to all countries is enabled. + * + * @return bool Flag that denotes whether shipping to all countries is enabled. + */ + public function isShipToAllCountries() + { + return $this->isShipToAllCountries; + } + + /** + * Sets flag that denotes whether shipping to all countries is enabled. + * + * @param boolean $isShipToAllCountries Flag that denotes whether shipping to all countries is enabled. + */ + public function setShipToAllCountries($isShipToAllCountries) + { + $this->isShipToAllCountries = $isShipToAllCountries; + } + /** * Sorts fixed price policies by ranges. * diff --git a/src/BusinessLogic/ShippingMethod/ShippingCostCalculator.php b/src/BusinessLogic/ShippingMethod/ShippingCostCalculator.php index f1f994de..0bad690e 100644 --- a/src/BusinessLogic/ShippingMethod/ShippingCostCalculator.php +++ b/src/BusinessLogic/ShippingMethod/ShippingCostCalculator.php @@ -8,6 +8,7 @@ use Packlink\BusinessLogic\Http\DTO\ShippingServiceDetails; use Packlink\BusinessLogic\Http\DTO\ShippingServiceSearch; use Packlink\BusinessLogic\Http\Proxy; +use Packlink\BusinessLogic\ShippingMethod\Exceptions\FixedPriceValueOutOfBoundsException; use Packlink\BusinessLogic\ShippingMethod\Models\ShippingMethod; use Packlink\BusinessLogic\ShippingMethod\Models\ShippingService; @@ -201,11 +202,15 @@ protected static function calculateShippingMethodCost( || ($methodService->departureCountry === $fromCountry && $methodService->destinationCountry === $toCountry) ) { - $baseCost = self::calculateCostForShippingMethod( - $shippingMethod, - $basePrice ?: $methodService->basePrice, - $totalAmount - ); + try { + $baseCost = self::calculateCostForShippingMethod( + $shippingMethod, + $basePrice ?: $methodService->basePrice, + $totalAmount + ); + } catch (FixedPriceValueOutOfBoundsException $e) { + return false; + } $cost = min($cost, $baseCost); } @@ -222,6 +227,8 @@ protected static function calculateShippingMethodCost( * @param float $totalAmount Total amount (weight or value). * * @return float Calculated shipping cost. + * + * @throws \Packlink\BusinessLogic\ShippingMethod\Exceptions\FixedPriceValueOutOfBoundsException */ protected static function calculateCostForShippingMethod( ShippingMethod $shippingMethod, @@ -245,6 +252,8 @@ protected static function calculateCostForShippingMethod( * @param float $total Total weight or value. * * @return float Calculated fixed price cost. + * + * @throws \Packlink\BusinessLogic\ShippingMethod\Exceptions\FixedPriceValueOutOfBoundsException */ protected static function calculateFixedPriceCost(ShippingMethod $shippingMethod, $total) { @@ -253,6 +262,12 @@ protected static function calculateFixedPriceCost(ShippingMethod $shippingMethod $fixedPricePolicies = $shippingMethod->getFixedPriceByValuePolicy(); } + self::sortFixedPricePolicy($fixedPricePolicies); + + if ($total < $fixedPricePolicies[0]->from) { + throw new FixedPriceValueOutOfBoundsException('Fixed price value out of bounds.'); + } + foreach ($fixedPricePolicies as $fixedPricePolicy) { if ($fixedPricePolicy->from <= $total && $fixedPricePolicy->to > $total) { return $fixedPricePolicy->amount; @@ -412,4 +427,24 @@ private static function preparePackages(array $packages = array()) return $transformer->transform($packages); } + + /** + * Sorts fixed price policies. + * + * @param \Packlink\BusinessLogic\ShippingMethod\Models\FixedPricePolicy[] $fixedPricePolicies + * Reference to an fixed price policy array. + */ + private static function sortFixedPricePolicy(&$fixedPricePolicies) + { + usort( + $fixedPricePolicies, + function ($a, $b) { + if ($a->from === $b->from) { + return 0; + } + + return $a->from < $b->from ? -1 : 1; + } + ); + } } diff --git a/src/BusinessLogic/ShippingMethod/Utility/ShipmentStatus.php b/src/BusinessLogic/ShippingMethod/Utility/ShipmentStatus.php index c85c45e8..50dda866 100644 --- a/src/BusinessLogic/ShippingMethod/Utility/ShipmentStatus.php +++ b/src/BusinessLogic/ShippingMethod/Utility/ShipmentStatus.php @@ -29,6 +29,10 @@ class ShipmentStatus * Status when shipment is completed. */ const STATUS_DELIVERED = 'delivered'; + /** + * Status when shipment is cancelled. + */ + const STATUS_CANCELLED = 'cancelled'; /** * Maps raw shipment status from Packlink to shipment status. @@ -63,16 +67,4 @@ public static function getStatus($shipmentStatus) return self::STATUS_PENDING; } } - - /** - * Returns whether shipment labels should be fetched. - * - * @param string $shipmentStatus Raw shipment status from Packlink. - * - * @return bool Returns TRUE if labels should be fetched; otherwise returns FALSE. - */ - public static function shouldFetchLabels($shipmentStatus) - { - return in_array($shipmentStatus, array('READY_TO_PRINT', 'READY_FOR_COLLECTION', 'IN_TRANSIT', 'DELIVERED')); - } } diff --git a/src/BusinessLogic/ShippingMethod/Validation/PricingPolicyValidator.php b/src/BusinessLogic/ShippingMethod/Validation/PricingPolicyValidator.php index 4625f4e6..96ac2448 100644 --- a/src/BusinessLogic/ShippingMethod/Validation/PricingPolicyValidator.php +++ b/src/BusinessLogic/ShippingMethod/Validation/PricingPolicyValidator.php @@ -29,7 +29,7 @@ public static function validateFixedPricePolicy($fixedPricePolicies, $allowZeroP if (count($fixedPricePolicies) > 0) { $count = count($fixedPricePolicies); $previous = $fixedPricePolicies[0]; - self::validateSingleFixedPricePolicy($previous, 0, $allowZeroPrice); + self::validateSingleFixedPricePolicy($previous, $previous->from, $allowZeroPrice); for ($i = 1; $i < $count; $i++) { self::validateSingleFixedPricePolicy($fixedPricePolicies[$i], $previous->to, $allowZeroPrice); @@ -66,7 +66,8 @@ public static function validatePercentPricePolicy(PercentPricePolicy $policy) */ protected static function validateSingleFixedPricePolicy($policy, $lowerBoundary, $allowZeroPrice = false) { - if ((float)$policy->from !== (float)$lowerBoundary + if ((float) $lowerBoundary < 0 + || (float)$policy->from !== (float)$lowerBoundary || $policy->from >= $policy->to || ($allowZeroPrice && $policy->amount < 0) || (!$allowZeroPrice && $policy->amount <= 0) diff --git a/src/BusinessLogic/Tasks/GetDefaultParcelAndWarehouseTask.php b/src/BusinessLogic/Tasks/GetDefaultParcelAndWarehouseTask.php index e90a0105..0843c512 100644 --- a/src/BusinessLogic/Tasks/GetDefaultParcelAndWarehouseTask.php +++ b/src/BusinessLogic/Tasks/GetDefaultParcelAndWarehouseTask.php @@ -12,6 +12,29 @@ */ class GetDefaultParcelAndWarehouseTask extends Task { + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static(); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array(); + } + /** * Runs task logic. * diff --git a/src/BusinessLogic/Tasks/SendDraftTask.php b/src/BusinessLogic/Tasks/SendDraftTask.php index 1e869556..08e158f1 100644 --- a/src/BusinessLogic/Tasks/SendDraftTask.php +++ b/src/BusinessLogic/Tasks/SendDraftTask.php @@ -3,10 +3,14 @@ namespace Packlink\BusinessLogic\Tasks; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Task; use Packlink\BusinessLogic\Http\Proxy; +use Packlink\BusinessLogic\Order\Models\OrderShipmentDetails; use Packlink\BusinessLogic\Order\OrderService; +use Packlink\BusinessLogic\OrderShipmentDetails\OrderShipmentDetailsService; /** * Class UploadDraftTask @@ -32,6 +36,12 @@ class SendDraftTask extends Task * @var Proxy */ private $proxy; + /** + * OrderShipmentDetailsService instance. + * + * @var OrderShipmentDetailsService + */ + private $orderShipmentDetailsService; /** * UploadDraftTask constructor. @@ -43,6 +53,29 @@ public function __construct($orderId) $this->orderId = $orderId; } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static($array['order_id']); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array('order_id' => $this->orderId); + } + /** * String representation of object * @@ -50,7 +83,7 @@ public function __construct($orderId) */ public function serialize() { - return serialize(array('orderId' => $this->orderId)); + return Serializer::serialize(array($this->orderId)); } /** @@ -64,8 +97,7 @@ public function serialize() */ public function unserialize($serialized) { - $data = unserialize($serialized); - $this->orderId = $data['orderId']; + list($this->orderId) = Serializer::unserialize($serialized); } /** @@ -75,9 +107,17 @@ public function unserialize($serialized) * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpCommunicationException * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpRequestException * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException */ public function execute() { + $isRepositoryRegistered = RepositoryRegistry::isRegistered(OrderShipmentDetails::getClassName()); + if ($isRepositoryRegistered && $this->isDraftCreated($this->orderId)) { + Logger::logWarning("Draft for order [{$this->orderId}] has been already created. Task is terminating."); + $this->reportProgress(100); + return; + } + $draft = $this->getOrderService()->prepareDraft($this->orderId); $this->reportProgress(35); @@ -93,6 +133,28 @@ public function execute() $this->reportProgress(100); } + /** + * Checks whether draft has already been created for a particular order. + * + * @param string $orderId Order id in an integrated system. + * + * @return boolean Returns TRUE if draft has been created; FALSE otherwise. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + */ + private function isDraftCreated($orderId) + { + $draft = $this->getOrderShipmentDetailsService()->getDetailsByOrderId($orderId); + + if ($draft === null) { + return false; + } + + $reference = $draft->getReference(); + + return !empty($reference); + } + /** * Returns proxy instance. * @@ -120,4 +182,18 @@ private function getOrderService() return $this->orderService; } + + /** + * Retrieves order-shipment details service. + * + * @return OrderShipmentDetailsService Service instance. + */ + private function getOrderShipmentDetailsService() + { + if ($this->orderShipmentDetailsService === null) { + $this->orderShipmentDetailsService = ServiceRegister::getService(OrderShipmentDetailsService::CLASS_NAME); + } + + return $this->orderShipmentDetailsService; + } } diff --git a/src/BusinessLogic/Tasks/UpdateShipmentDataTask.php b/src/BusinessLogic/Tasks/UpdateShipmentDataTask.php index 558da32c..34b44a0e 100644 --- a/src/BusinessLogic/Tasks/UpdateShipmentDataTask.php +++ b/src/BusinessLogic/Tasks/UpdateShipmentDataTask.php @@ -3,8 +3,10 @@ namespace Packlink\BusinessLogic\Tasks; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Task; +use Packlink\BusinessLogic\Http\DTO\Shipment; use Packlink\BusinessLogic\Http\Proxy; use Packlink\BusinessLogic\Order\Exceptions\OrderNotFound; use Packlink\BusinessLogic\Order\Interfaces\OrderRepository; @@ -36,6 +38,12 @@ class UpdateShipmentDataTask extends Task * @var array */ protected $references = array(); + /** + * List of order statuses that should be used when retrieving references to check for updates. + * + * @var array + */ + protected $orderStatuses = array(); /** * @var \Packlink\BusinessLogic\Order\Interfaces\OrderRepository */ @@ -53,16 +61,62 @@ class UpdateShipmentDataTask extends Task */ private $proxy; + /** + * UpdateShipmentDataTask constructor. + * + * @param array $orderStatuses + */ + public function __construct(array $orderStatuses = array()) + { + $this->orderStatuses = $orderStatuses; + } + + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + $entity = new static(); + + $entity->progress = $array['progress']; + $entity->progressStep = $array['progress_step']; + $entity->references = $array['references']; + $entity->orderStatuses = isset($array['order_statues']) ? $array['order_statues'] : array(); + + return $entity; + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array( + 'progress' => $this->progress, + 'progress_step' => $this->progressStep, + 'references' => $this->references, + 'order_statuses' => $this->orderStatuses, + ); + } + /** * @inheritdoc */ public function serialize() { - return serialize( + return Serializer::serialize( array( $this->references, $this->progress, $this->progressStep, + $this->orderStatuses, ) ); } @@ -72,7 +126,13 @@ public function serialize() */ public function unserialize($serialized) { - list($this->references, $this->progress, $this->progressStep) = unserialize($serialized); + $original = Serializer::unserialize($serialized); + + if (count($original) === 3) { + list($this->references, $this->progress, $this->progressStep) = $original; + } else { + list($this->references, $this->progress, $this->progressStep, $this->orderStatuses) = $original; + } } /** @@ -83,7 +143,7 @@ public function unserialize($serialized) public function execute() { if (empty($this->references) && $this->progress === 0) { - $this->initializeState(); + $this->initializeState($this->orderStatuses); } while (!empty($this->references)) { @@ -103,10 +163,16 @@ public function execute() /** * Initializes needed parameters for the task execution. + * + * @param array $orderStatuses List of order statuses. */ - protected function initializeState() + protected function initializeState(array $orderStatuses = array()) { - $this->references = $this->getOrderRepository()->getIncompleteOrderReferences(); + if (empty($orderStatuses)) { + $this->references = $this->getOrderRepository()->getIncompleteOrderReferences(); + } else { + $this->references = $this->getOrderRepository()->getOrderReferencesWithStatus($orderStatuses); + } $this->progress = 5; $this->reportProgress($this->progress); @@ -132,10 +198,11 @@ protected function updateOrderShipmentData($reference) $shipment = $this->getProxy()->getShipment($reference); if ($shipment !== null) { $orderService = $this->getOrderService(); - $orderService->updateTrackingInfo($shipment); - $orderService->updateShipmentLabel($shipment); - $orderService->updateShippingStatus($shipment, ShipmentStatus::getStatus($shipment->status)); + if ($this->isTrackingInfoUpdatable($shipment)) { + $orderService->updateTrackingInfo($shipment); + } + $orderService->updateShippingStatus($shipment, ShipmentStatus::getStatus($shipment->status)); $orderRepository->setShippingPriceByReference($reference, (float)$shipment->price); } else { $orderRepository->markShipmentDeleted($reference); @@ -184,4 +251,22 @@ protected function getOrderService() return $this->orderService; } + + /** + * Checks if tracking info should be updated. + * + * @param \Packlink\BusinessLogic\Http\DTO\Shipment $shipment Shipment instance to be checked for updatability. + * + * @return bool TRUE if tracking info should be update; FALSE otherwise. + */ + protected function isTrackingInfoUpdatable(Shipment $shipment) + { + $allowedUpdateStatuses = array( + ShipmentStatus::STATUS_ACCEPTED, + ShipmentStatus::STATUS_READY, + ShipmentStatus::STATUS_IN_TRANSIT, + ); + + return in_array(ShipmentStatus::getStatus($shipment->status), $allowedUpdateStatuses, true); + } } diff --git a/src/BusinessLogic/Tasks/UpdateShippingServicesTask.php b/src/BusinessLogic/Tasks/UpdateShippingServicesTask.php index 8941c0bf..43a73561 100644 --- a/src/BusinessLogic/Tasks/UpdateShippingServicesTask.php +++ b/src/BusinessLogic/Tasks/UpdateShippingServicesTask.php @@ -39,6 +39,29 @@ class UpdateShippingServicesTask extends Task 'US' => '10001', ); + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static(); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array(); + } + /** * Gets all local methods and remote services and synchronizes data. * diff --git a/src/BusinessLogic/User/UserAccountService.php b/src/BusinessLogic/User/UserAccountService.php index 149fe439..94803021 100644 --- a/src/BusinessLogic/User/UserAccountService.php +++ b/src/BusinessLogic/User/UserAccountService.php @@ -13,9 +13,11 @@ use Packlink\BusinessLogic\Http\DTO\Analytics; use Packlink\BusinessLogic\Http\DTO\User; use Packlink\BusinessLogic\Http\Proxy; +use Packlink\BusinessLogic\Scheduler\Models\DailySchedule; use Packlink\BusinessLogic\Scheduler\Models\HourlySchedule; use Packlink\BusinessLogic\Scheduler\Models\Schedule; use Packlink\BusinessLogic\Scheduler\Models\WeeklySchedule; +use Packlink\BusinessLogic\ShippingMethod\Utility\ShipmentStatus; use Packlink\BusinessLogic\Tasks\UpdateShipmentDataTask; use Packlink\BusinessLogic\Tasks\UpdateShippingServicesTask; @@ -41,7 +43,7 @@ class UserAccountService extends BaseService * * @var Configuration */ - private $configuration; + protected $configuration; /** * Proxy instance. * @@ -104,6 +106,10 @@ public function setDefaultParcel($force) { $parcelInfo = $this->configuration->getDefaultParcel(); if ($parcelInfo === null || $force) { + if ($this->setParcelInfoInternal()) { + return; + } + $parcels = $this->getProxy()->getUsersParcelInfo(); foreach ($parcels as $parcel) { if ($parcel->default) { @@ -129,6 +135,10 @@ public function setWarehouseInfo($force) { $warehouse = $this->configuration->getDefaultWarehouse(); if ($warehouse === null || $force) { + if ($this->setWarehouseInfoInternal()) { + return; + } + $usersWarehouses = $this->getProxy()->getUsersWarehouses(); foreach ($usersWarehouses as $usersWarehouse) { if ($usersWarehouse->default) { @@ -177,6 +187,28 @@ protected function initializeUser(User $user) $this->getProxy()->sendAnalytics(Analytics::EVENT_CONFIGURATION); } + /** + * Internal method for setting warehouse info in integrations. + * If integration set it, Core will not fetch the info from Packlink API. + * + * @return bool + */ + protected function setWarehouseInfoInternal() + { + return false; + } + + /** + * Internal method for setting default parcel info in integrations. + * If integration set it, Core will not fetch the info from Packlink API. + * + * @return bool + */ + protected function setParcelInfoInternal() + { + return false; + } + /** * Creates schedules. * @@ -201,6 +233,9 @@ protected function createSchedules() // Schedule hourly task for updating shipment info - start at half hour $this->setHourlyTask($repository, 30); + + // Schedule daily task for updating shipment info - start at 11:00 UTC hour + $this->setDailyTask($repository, 11); } /** @@ -211,8 +246,12 @@ protected function createSchedules() */ protected function setHourlyTask(RepositoryInterface $repository, $minute) { + $hourlyStatuses = array( + ShipmentStatus::STATUS_PENDING, + ); + $shipmentDataHalfHourSchedule = new HourlySchedule( - new UpdateShipmentDataTask(), + new UpdateShipmentDataTask($hourlyStatuses), $this->configuration->getDefaultQueueName() ); $shipmentDataHalfHourSchedule->setMinute($minute); @@ -220,6 +259,34 @@ protected function setHourlyTask(RepositoryInterface $repository, $minute) $repository->save($shipmentDataHalfHourSchedule); } + /** + * Schedules daily shipment data update task. + * + * @param RepositoryInterface $repository Schedule repository. + * @param int $hour Hour of the day when schedule should be executed. + */ + protected function setDailyTask(RepositoryInterface $repository, $hour) + { + $dailyStatuses = array( + ShipmentStatus::STATUS_IN_TRANSIT, + ShipmentStatus::STATUS_READY, + ShipmentStatus::STATUS_ACCEPTED, + ); + + $dailyShipmentDataSchedule = new DailySchedule( + new UpdateShipmentDataTask( + $dailyStatuses + ), + $this->configuration->getDefaultQueueName(), + $this->configuration->getContext() + ); + + $dailyShipmentDataSchedule->setHour($hour); + $dailyShipmentDataSchedule->setNextSchedule(); + + $repository->save($dailyShipmentDataSchedule); + } + /** * Gets Proxy. * diff --git a/src/BusinessLogic/Utility/Php/Php55.php b/src/BusinessLogic/Utility/Php/Php55.php index aef21f47..5c5cb88c 100644 --- a/src/BusinessLogic/Utility/Php/Php55.php +++ b/src/BusinessLogic/Utility/Php/Php55.php @@ -29,7 +29,7 @@ * * @internal */ -final class Php55 +class Php55 { /** * Return the values from a single column in the input array. diff --git a/src/BusinessLogic/WebHook/WebHookEventHandler.php b/src/BusinessLogic/WebHook/WebHookEventHandler.php index cca06ad8..cb011b13 100644 --- a/src/BusinessLogic/WebHook/WebHookEventHandler.php +++ b/src/BusinessLogic/WebHook/WebHookEventHandler.php @@ -126,9 +126,6 @@ protected function handleEvent($eventName, $eventData) case 'shipment.delivered': $orderService->updateShippingStatus($shipment, ShipmentStatus::STATUS_DELIVERED); break; - case 'shipment.label.ready': - $orderService->updateShipmentLabel($shipment); - break; case 'shipment.tracking.update': $orderService->updateTrackingInfo($shipment); break; diff --git a/src/Infrastructure/AutoTest/AutoTestTask.php b/src/Infrastructure/AutoTest/AutoTestTask.php index f90d87d9..78a42f19 100644 --- a/src/Infrastructure/AutoTest/AutoTestTask.php +++ b/src/Infrastructure/AutoTest/AutoTestTask.php @@ -3,6 +3,7 @@ namespace Logeecom\Infrastructure\AutoTest; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Task; /** @@ -29,6 +30,29 @@ public function __construct($data) $this->data = $data; } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static($array['data']); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array('data' => $this->data); + } + /** * String representation of object. * @@ -36,7 +60,7 @@ public function __construct($data) */ public function serialize() { - return serialize(array('data' => $this->data)); + return Serializer::serialize(array($this->data)); } /** @@ -48,8 +72,7 @@ public function serialize() */ public function unserialize($serialized) { - $data = unserialize($serialized); - $this->data = $data['data']; + list($this->data) = Serializer::unserialize($serialized); } /** diff --git a/src/Infrastructure/ORM/QueryFilter/Operators.php b/src/Infrastructure/ORM/QueryFilter/Operators.php index 5f67d96e..b751c498 100644 --- a/src/Infrastructure/ORM/QueryFilter/Operators.php +++ b/src/Infrastructure/ORM/QueryFilter/Operators.php @@ -7,7 +7,7 @@ * * @package Logeecom\Infrastructure\ORM\QueryFilter */ -final class Operators +class Operators { const EQUALS = '='; const NOT_EQUALS = '!='; diff --git a/src/Infrastructure/ORM/RepositoryRegistry.php b/src/Infrastructure/ORM/RepositoryRegistry.php index 6dccae3a..5212b632 100644 --- a/src/Infrastructure/ORM/RepositoryRegistry.php +++ b/src/Infrastructure/ORM/RepositoryRegistry.php @@ -35,7 +35,7 @@ class RepositoryRegistry */ public static function getRepository($entityClass) { - if (!array_key_exists($entityClass, self::$repositories)) { + if (!self::isRegistered($entityClass)) { throw new RepositoryNotRegisteredException("Repository for entity $entityClass not found or registered."); } @@ -68,6 +68,18 @@ public static function registerRepository($entityClass, $repositoryClass) self::$repositories[$entityClass] = $repositoryClass; } + /** + * Checks whether repository has been registered for a particular entity. + * + * @param string $entityClass Entity for which check has to be performed. + * + * @return boolean Returns TRUE if repository has been registered; FALSE otherwise. + */ + public static function isRegistered($entityClass) + { + return isset(self::$repositories[$entityClass]); + } + /** * Returns queue item repository. * diff --git a/src/Infrastructure/ORM/Utility/EntityTranslator.php b/src/Infrastructure/ORM/Utility/EntityTranslator.php index e325ec37..898437c2 100644 --- a/src/Infrastructure/ORM/Utility/EntityTranslator.php +++ b/src/Infrastructure/ORM/Utility/EntityTranslator.php @@ -8,6 +8,7 @@ /** * Class EntityTranslator + * * @package Logeecom\Infrastructure\ORM\Utility */ class EntityTranslator @@ -63,8 +64,15 @@ public function translate(array $intermediateObjects) */ private function translateOne(IntermediateObject $intermediateObject) { + $data = json_decode($intermediateObject->getData(), true); + + if (!$data['class_name']) { + throw new EntityClassException('Entity has not provided class name.'); + } + /** @var Entity $entity */ - $entity = unserialize($intermediateObject->getData()); + $entity = new $data['class_name']; + $entity->inflate($data); if (!($entity instanceof $this->entityClass)) { throw new EntityClassException("Unserialized entity is not of class {$this->entityClass}"); } diff --git a/src/Infrastructure/Serializer/Concrete/JsonSerializer.php b/src/Infrastructure/Serializer/Concrete/JsonSerializer.php new file mode 100644 index 00000000..d270b03e --- /dev/null +++ b/src/Infrastructure/Serializer/Concrete/JsonSerializer.php @@ -0,0 +1,57 @@ +className = get_class($data); + } + + return json_encode($data, true); + } + + $preparedArray = $data->toArray(); + $preparedArray['class_name'] = get_class($data); + + return json_encode($preparedArray); + } + + /** + * Unserializes data. + * + * @param string $serialized Serialized data. + * + * @return mixed Unserialized data. + */ + protected function doUnserialize($serialized) + { + $unserialized = json_decode($serialized, true); + + if (!is_array($unserialized) || !array_key_exists('class_name', $unserialized)) { + return $unserialized; + } + + $class = $unserialized['class_name']; + unset($unserialized['class_name']); + + return $class::fromArray($unserialized); + } +} \ No newline at end of file diff --git a/src/Infrastructure/Serializer/Concrete/NativeSerializer.php b/src/Infrastructure/Serializer/Concrete/NativeSerializer.php new file mode 100644 index 00000000..c5d44574 --- /dev/null +++ b/src/Infrastructure/Serializer/Concrete/NativeSerializer.php @@ -0,0 +1,43 @@ +doSerialize($data); + } + + /** + * Unserializes data. + * + * @param string $serialized Serialized data. + * + * @return mixed Unserialized data. + */ + public static function unserialize($serialized) + { + /** @var Serializer $instace */ + $instance = ServiceRegister::getService(self::CLASS_NAME); + + return $instance->doUnserialize($serialized); + } + + /** + * Serializes data. + * + * @param mixed $data Data to be serialized. + * + * @return string String representation of the serialized data. + */ + abstract protected function doSerialize($data); + + /** + * Unserializes data. + * + * @param string $serialized Serialized data. + * + * @return mixed Unserialized data. + */ + abstract protected function doUnserialize($serialized); +} \ No newline at end of file diff --git a/src/Infrastructure/TaskExecution/CompositeTask.php b/src/Infrastructure/TaskExecution/CompositeTask.php index 53248f85..36c2470c 100644 --- a/src/Infrastructure/TaskExecution/CompositeTask.php +++ b/src/Infrastructure/TaskExecution/CompositeTask.php @@ -2,6 +2,7 @@ namespace Logeecom\Infrastructure\TaskExecution; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\TaskEvents\AliveAnnouncedTaskEvent; use Logeecom\Infrastructure\TaskExecution\TaskEvents\TaskProgressEvent; @@ -61,12 +62,56 @@ public function __construct(array $subTasks, $initialProgress = 0) } } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + $tasks = array(); + + foreach ($array['tasks'] as $task) { + $tasks[] = Serializer::unserialize($task); + } + + $entity = new static($tasks, $array['initial_progress']); + $entity->taskProgressMap = $array['task_progress_map']; + $entity->tasksProgressShare = $array['tasks_progress_share']; + + return $entity; + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + $tasks = array(); + + foreach ($this->tasks as $task) { + $tasks[] = Serializer::serialize($task); + } + + return array( + 'initial_progress' => $this->initialProgress, + 'task_progress_map' => $this->taskProgressMap, + 'tasks_progress_share' => $this->tasksProgressShare, + 'tasks' => $tasks + ); + } + /** * @inheritdoc */ public function serialize() { - return serialize( + return Serializer::serialize( array( 'initialProgress' => $this->initialProgress, 'taskProgress' => $this->taskProgressMap, @@ -81,7 +126,7 @@ public function serialize() */ public function unserialize($serialized) { - $unserializedStateData = unserialize($serialized); + $unserializedStateData = Serializer::unserialize($serialized); $this->initialProgress = $unserializedStateData['initialProgress']; $this->taskProgressMap = $unserializedStateData['taskProgress']; diff --git a/src/Infrastructure/TaskExecution/Interfaces/Runnable.php b/src/Infrastructure/TaskExecution/Interfaces/Runnable.php index bbc7be51..e7d2d851 100644 --- a/src/Infrastructure/TaskExecution/Interfaces/Runnable.php +++ b/src/Infrastructure/TaskExecution/Interfaces/Runnable.php @@ -2,12 +2,14 @@ namespace Logeecom\Infrastructure\TaskExecution\Interfaces; +use Logeecom\Infrastructure\Serializer\Interfaces\Serializable; + /** * Interface Runnable. * * @package Logeecom\Infrastructure\TaskExecution\Interfaces */ -interface Runnable extends \Serializable +interface Runnable extends Serializable { /** * Starts runnable run logic diff --git a/src/Infrastructure/TaskExecution/Process.php b/src/Infrastructure/TaskExecution/Process.php index c272448b..f84be06c 100644 --- a/src/Infrastructure/TaskExecution/Process.php +++ b/src/Infrastructure/TaskExecution/Process.php @@ -5,6 +5,7 @@ use Logeecom\Infrastructure\ORM\Configuration\EntityConfiguration; use Logeecom\Infrastructure\ORM\Configuration\IndexMap; use Logeecom\Infrastructure\ORM\Entity; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Interfaces\Runnable; /** @@ -45,7 +46,7 @@ public function inflate(array $data) parent::inflate($data); $this->setGuid($data['guid']); - $this->setRunner(unserialize($data['runner'])); + $this->setRunner(Serializer::unserialize($data['runner'])); } /** @@ -57,7 +58,7 @@ public function toArray() { $data = parent::toArray(); $data['guid'] = $this->getGuid(); - $data['runner'] = serialize($this->getRunner()); + $data['runner'] = Serializer::serialize($this->getRunner()); return $data; } diff --git a/src/Infrastructure/TaskExecution/QueueItem.php b/src/Infrastructure/TaskExecution/QueueItem.php index cb827029..ed6cd824 100644 --- a/src/Infrastructure/TaskExecution/QueueItem.php +++ b/src/Infrastructure/TaskExecution/QueueItem.php @@ -6,6 +6,7 @@ use Logeecom\Infrastructure\ORM\Configuration\EntityConfiguration; use Logeecom\Infrastructure\ORM\Configuration\IndexMap; use Logeecom\Infrastructure\ORM\Entity; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Exceptions\QueueItemDeserializationException; use Logeecom\Infrastructure\TaskExecution\TaskEvents\AliveAnnouncedTaskEvent; @@ -389,7 +390,7 @@ public function getTaskType() public function getTask() { if ($this->task === null) { - $this->task = @unserialize($this->serializedTask); + $this->task = Serializer::unserialize($this->serializedTask); if (empty($this->task)) { throw new QueueItemDeserializationException( json_encode( @@ -420,7 +421,7 @@ public function getSerializedTask() return $this->serializedTask; } - return serialize($this->task); + return Serializer::serialize($this->task); } /** diff --git a/src/Infrastructure/TaskExecution/QueueItemStarter.php b/src/Infrastructure/TaskExecution/QueueItemStarter.php index 80dd852d..f76703a6 100644 --- a/src/Infrastructure/TaskExecution/QueueItemStarter.php +++ b/src/Infrastructure/TaskExecution/QueueItemStarter.php @@ -4,6 +4,7 @@ use Logeecom\Infrastructure\Configuration\Configuration; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Interfaces\Runnable; @@ -42,12 +43,35 @@ public function __construct($queueItemId) $this->queueItemId = $queueItemId; } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static($array['queue_item_id']); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array('queue_item_id' => $this->queueItemId); + } + /** * @inheritdoc */ public function serialize() { - return serialize(array($this->queueItemId)); + return Serializer::serialize(array($this->queueItemId)); } /** @@ -55,7 +79,7 @@ public function serialize() */ public function unserialize($serialized) { - list($this->queueItemId) = unserialize($serialized); + list($this->queueItemId) = Serializer::unserialize($serialized); } /** diff --git a/src/Infrastructure/TaskExecution/Task.php b/src/Infrastructure/TaskExecution/Task.php index 7df7a50a..a7672f97 100644 --- a/src/Infrastructure/TaskExecution/Task.php +++ b/src/Infrastructure/TaskExecution/Task.php @@ -3,6 +3,8 @@ namespace Logeecom\Infrastructure\TaskExecution; use Logeecom\Infrastructure\Configuration\Configuration; +use Logeecom\Infrastructure\Serializer\Interfaces\Serializable; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\TaskEvents\AliveAnnouncedTaskEvent; use Logeecom\Infrastructure\TaskExecution\TaskEvents\TaskProgressEvent; @@ -13,7 +15,7 @@ * Class Task * @package Logeecom\Infrastructure\TaskExecution */ -abstract class Task extends EventEmitter implements \Serializable +abstract class Task extends EventEmitter implements Serializable { /** * Max inactivity period for a task in seconds @@ -52,7 +54,7 @@ abstract public function execute(); */ public function serialize() { - return serialize(array()); + return Serializer::serialize(array()); } /** diff --git a/src/Infrastructure/TaskExecution/TaskRunnerStarter.php b/src/Infrastructure/TaskExecution/TaskRunnerStarter.php index 276ee6c1..563c2ec2 100644 --- a/src/Infrastructure/TaskExecution/TaskRunnerStarter.php +++ b/src/Infrastructure/TaskExecution/TaskRunnerStarter.php @@ -3,6 +3,7 @@ namespace Logeecom\Infrastructure\TaskExecution; use Logeecom\Infrastructure\Logger\Logger; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\ServiceRegister; use Logeecom\Infrastructure\TaskExecution\Exceptions\TaskRunnerRunException; use Logeecom\Infrastructure\TaskExecution\Exceptions\TaskRunnerStatusStorageUnavailableException; @@ -54,6 +55,29 @@ public function __construct($guid) $this->guid = $guid; } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + return new static($array['guid']); + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array('guid' => $this->guid); + } + /** * String representation of object. * @@ -61,7 +85,7 @@ public function __construct($guid) */ public function serialize() { - return serialize(array($this->guid)); + return Serializer::serialize(array($this->guid)); } /** @@ -71,7 +95,7 @@ public function serialize() */ public function unserialize($serialized) { - list($this->guid) = unserialize($serialized); + list($this->guid) = Serializer::unserialize($serialized); } /** diff --git a/tests/BusinessLogic/Common/TestComponents/Order/TestOrderRepository.php b/tests/BusinessLogic/Common/TestComponents/Order/TestOrderRepository.php index 4d420e8e..44616993 100644 --- a/tests/BusinessLogic/Common/TestComponents/Order/TestOrderRepository.php +++ b/tests/BusinessLogic/Common/TestComponents/Order/TestOrderRepository.php @@ -46,6 +46,8 @@ class TestOrderRepository implements OrderRepository */ private $incompleteOrderReferences = array('test'); + private $ordersInStatuses = array('test'); + /** * TestOrderRepository constructor. */ @@ -316,18 +318,18 @@ public function getOrder($orderId, $shippingMethodId = 0, $destinationCountry = } /** - * Returns whether shipment identified by provided reference has Packlink shipment labels set. + * Retrieves list of order references where order is in one of the provided statuses. * - * @param string $shipmentReference Packlink shipment reference. + * @param array $statuses List of order statuses. * - * @return bool Returns TRUE if labels are set; otherwise returns FALSE. + * @return string[] Array of shipment references. */ - public function isLabelSet($shipmentReference) + public function getOrderReferencesWithStatus(array $statuses) { - $order = $this->getOrder($shipmentReference, 0, '', false); - - $packlinkShipmentLabels = $order->getPacklinkShipmentLabels(); + if ($this->throwGenericException) { + throw new \RuntimeException('Error'); + } - return !empty($packlinkShipmentLabels); + return $this->ordersInStatuses; } } diff --git a/tests/BusinessLogic/Controllers/ShippingMethodControllerTest.php b/tests/BusinessLogic/Controllers/ShippingMethodControllerTest.php index 3546e970..0515d390 100644 --- a/tests/BusinessLogic/Controllers/ShippingMethodControllerTest.php +++ b/tests/BusinessLogic/Controllers/ShippingMethodControllerTest.php @@ -109,6 +109,8 @@ public function testSaveChangeNameAndShowImage() $shipment->name = 'First name test'; $shipment->showLogo = !$first->showLogo; $shipment->pricePolicy = $first->pricePolicy; + $shipment->isShipToAllCountries = true; + $shipment->shippingCountries = array(); $model = $this->controller->save($shipment); @@ -287,6 +289,8 @@ public function testSaveCorrectPricePolicy() $shipment->id = $first->id; $shipment->name = 'First name test'; $shipment->showLogo = !$first->showLogo; + $shipment->isShipToAllCountries = true; + $shipment->shippingCountries = array(); $shipment->pricePolicy = ShippingMethod::PRICING_POLICY_PERCENT; $shipment->percentPricePolicy = new PercentPricePolicy(true, 0.1); diff --git a/tests/BusinessLogic/Order/OrderServiceTest.php b/tests/BusinessLogic/Order/OrderServiceTest.php index 60caf551..177fd815 100644 --- a/tests/BusinessLogic/Order/OrderServiceTest.php +++ b/tests/BusinessLogic/Order/OrderServiceTest.php @@ -3,7 +3,6 @@ namespace Logeecom\Tests\BusinessLogic\Order; use Logeecom\Infrastructure\Http\HttpClient; -use Logeecom\Infrastructure\Http\HttpResponse; use Logeecom\Infrastructure\ORM\RepositoryRegistry; use Logeecom\Tests\BusinessLogic\Common\BaseTestWithServices; use Logeecom\Tests\BusinessLogic\Common\TestComponents\Order\TestOrderRepository; @@ -13,7 +12,6 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use Packlink\BusinessLogic\Configuration; use Packlink\BusinessLogic\Http\DTO\ParcelInfo; -use Packlink\BusinessLogic\Http\DTO\Shipment; use Packlink\BusinessLogic\Http\DTO\ShippingServiceDetails; use Packlink\BusinessLogic\Http\DTO\Warehouse; use Packlink\BusinessLogic\Http\Proxy; @@ -169,7 +167,7 @@ public function testPrepareDraftWrongDestinationCountry() $logMessages = $this->shopLogger->loggedMessages; self::assertCount(2, $logMessages); - self::assertEquals('Missing required search parameter(s).', $logMessages[0]->getMessage()); + self::assertEquals('Missing required search parameter(s).', $logMessages[0]->getMessage()); self::assertEquals( 'Invalid service method ' . $method->getId() . ' selected for order test because this method ' . 'does not support order\'s destination country. Sending order without selected method.', @@ -230,61 +228,6 @@ public function testSetReferenceNoOrder() $this->orderService->setReference('123', ''); } - public function testUpdateShipmentLabel() - { - $this->httpClient->setMockResponses(array( - new HttpResponse( - 200, array(), file_get_contents(__DIR__ . '/../Common/ApiResponses/shipmentLabels.json') - ) - )); - - $this->orderService->updateShipmentLabel($this->getShipment()); - - /** @var TestOrderRepository $orderRepository */ - $orderRepository = TestServiceRegister::getService(OrderRepository::CLASS_NAME); - $order = $orderRepository->getOrder('test'); - - $this->assertNotEmpty($order->getPacklinkShipmentLabels()); - } - - public function testUpdateShipmentLabelAlreadySet() - { - $this->httpClient->setMockResponses(array( - new HttpResponse( - 200, array(), file_get_contents(__DIR__ . '/../Common/ApiResponses/shipmentLabels.json') - ), - new HttpResponse( - 200, array(), file_get_contents(__DIR__ . '/../Common/ApiResponses/shipmentLabels.json') - ), - )); - - $shipment = $this->getShipment(); - // First call - $this->orderService->updateShipmentLabel($shipment); - - // Second call, should not make API call - $this->orderService->updateShipmentLabel($shipment); - - // Only one call to Packlink API - $this->assertCount(1, $this->httpClient->getHistory()); - } - - public function testUpdateShipmentLabelWrongStatus() - { - $this->orderService->updateShipmentLabel($this->getShipment('AWAITING_COMPLETION')); - - $this->assertNull($this->httpClient->getHistory()); - } - - private function getShipment($status = 'READY_TO_PRINT', $reference = 'test') - { - $shipment = new Shipment(); - $shipment->reference = $reference; - $shipment->status = $status; - - return $shipment; - } - private function getShippingServiceDetails($id, $carrierName, $basePrice = 10.76, $toCountry = 'IT') { $details = ShippingServiceDetails::fromArray( diff --git a/tests/BusinessLogic/Order/OrderShipmentDetailsEntityTest.php b/tests/BusinessLogic/Order/OrderShipmentDetailsEntityTest.php index e0d37f6e..fcbc787b 100644 --- a/tests/BusinessLogic/Order/OrderShipmentDetailsEntityTest.php +++ b/tests/BusinessLogic/Order/OrderShipmentDetailsEntityTest.php @@ -2,6 +2,7 @@ namespace Logeecom\Tests\BusinessLogic\Order; +use Packlink\BusinessLogic\Http\DTO\ShipmentLabel; use Packlink\BusinessLogic\Order\Models\OrderShipmentDetails; use PHPUnit\Framework\TestCase; @@ -97,7 +98,7 @@ private function getTestOrderDetails() $orderDetails->setOrderId(5); $orderDetails->setReference('DE2019PRO0000309473'); $orderDetails->setDropOffId(23); - $orderDetails->setShipmentLabels(array('test1.dev', 'test2.dev')); + $orderDetails->setShipmentLabels(array(new ShipmentLabel('test1.dev'), new ShipmentLabel('test2.dev'))); $orderDetails->setShippingStatus('pending', 1554192735); $orderDetails->setCarrierTrackingNumbers($this->getTestTrackingNumbers()); $orderDetails->setCarrierTrackingUrl('https://www.ups.com/track?loc=it_IT&requester=WT/'); diff --git a/tests/BusinessLogic/Scheduler/ScheduleCheckTaskTest.php b/tests/BusinessLogic/Scheduler/ScheduleCheckTaskTest.php index 363f4198..0ab5161b 100644 --- a/tests/BusinessLogic/Scheduler/ScheduleCheckTaskTest.php +++ b/tests/BusinessLogic/Scheduler/ScheduleCheckTaskTest.php @@ -10,6 +10,8 @@ use Logeecom\Infrastructure\ORM\QueryFilter\Operators; use Logeecom\Infrastructure\ORM\QueryFilter\QueryFilter; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Interfaces\TaskRunnerWakeup; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\TaskExecution\QueueService; @@ -36,6 +38,7 @@ /** * Class ScheduleCheckTaskTest + * * @package Logeecom\Tests\BusinessLogic\Scheduler */ class ScheduleCheckTaskTest extends TestCase @@ -118,6 +121,9 @@ public function setUp() EventBus::CLASS_NAME => function () { return EventBus::getInstance(); }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); diff --git a/tests/BusinessLogic/Scheduler/ScheduleTickHandlerTest.php b/tests/BusinessLogic/Scheduler/ScheduleTickHandlerTest.php index fbb85a19..8b5d8f62 100644 --- a/tests/BusinessLogic/Scheduler/ScheduleTickHandlerTest.php +++ b/tests/BusinessLogic/Scheduler/ScheduleTickHandlerTest.php @@ -5,6 +5,8 @@ use Logeecom\Infrastructure\Configuration\Configuration; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Interfaces\TaskRunnerWakeup; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\TaskExecution\QueueService; @@ -86,6 +88,9 @@ protected function setUp() EventBus::CLASS_NAME => function () { return EventBus::getInstance(); }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); diff --git a/tests/BusinessLogic/ShippingMethod/ShippingMethodEntityTest.php b/tests/BusinessLogic/ShippingMethod/ShippingMethodEntityTest.php index 8c0025ed..7c0a1d21 100644 --- a/tests/BusinessLogic/ShippingMethod/ShippingMethodEntityTest.php +++ b/tests/BusinessLogic/ShippingMethod/ShippingMethodEntityTest.php @@ -32,6 +32,9 @@ class ShippingMethodEntityTest extends TestCase */ public $httpClient; + /** + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryClassException + */ protected function setUp() { parent::setUp(); @@ -185,12 +188,12 @@ public function testFixedPricingPolicyValidationZeroAmountOnFirst() /** * @expectedException \InvalidArgumentException */ - public function testFixedPricingPolicyValidationFromNotZeroOnFirst() + public function testFixedPricingPolicyValidationFromNegative() { $method = new ShippingMethod(); /** @var FixedPricePolicy[] $fixedPricePolicies */ - $fixedPricePolicies[] = new FixedPricePolicy(3, 10, 10); + $fixedPricePolicies[] = new FixedPricePolicy(-3, 10, 10); // from for first policy must be 0 $method->setFixedPriceByWeightPolicy($fixedPricePolicies); @@ -698,6 +701,11 @@ public function testCheapestServiceProxyResponse() ); } + /** + * Asserts basic shipping method data. + * + * @return \Packlink\BusinessLogic\ShippingMethod\Models\ShippingMethod + */ private function assertBasicDataToArray() { $data = $this->getShippingMethodData(); diff --git a/tests/BusinessLogic/ShippingMethod/ShippingMethodServiceCostsTest.php b/tests/BusinessLogic/ShippingMethod/ShippingMethodServiceCostsTest.php index c550ee29..ccc6d0ea 100644 --- a/tests/BusinessLogic/ShippingMethod/ShippingMethodServiceCostsTest.php +++ b/tests/BusinessLogic/ShippingMethod/ShippingMethodServiceCostsTest.php @@ -22,6 +22,11 @@ use Packlink\BusinessLogic\ShippingMethod\ShippingCostCalculator; use Packlink\BusinessLogic\ShippingMethod\ShippingMethodService; +/** + * Class ShippingMethodServiceCostsTest + * + * @package Packlink\Tests\BusinessLogic\Tasks + */ class ShippingMethodServiceCostsTest extends BaseTestWithServices { /** @@ -416,6 +421,30 @@ public function testCalculateCostFixedPricingPolicy() self::assertEquals(12, $cost, 'Calculated cost is wrong!'); } + public function testCalculateFixedPricingPolicyOutOfBounds() + { + $shippingMethod = $this->prepareFixedPricePolicyShippingMethod( + 1, + array( + new FixedPricePolicy(10, 20, 12), + new FixedPricePolicy(5, 10, 12), + ) + ); + + $this->httpClient->setMockResponses(array(new HttpResponse(404, array(), ''))); + $cost = $this->shippingMethodService->getShippingCost( + $shippingMethod->getId(), + 'IT', + '00127', + 'IT', + '00127', + array(Package::defaultPackage()), + 2 + ); + + $this->assertEmpty($cost); + } + public function testCalculateCostsFixedPricingByWeightPolicy() { $this->calculateCostsFixedPricingPolicy(true); @@ -426,6 +455,11 @@ public function testCalculateCostsFixedPricingByValuePolicy() $this->calculateCostsFixedPricingPolicy(false); } + /** + * Calculates fixed price cost. + * + * @param float $byWeight + */ private function calculateCostsFixedPricingPolicy($byWeight) { $serviceId = 20339; @@ -839,6 +873,19 @@ protected function addShippingMethod($serviceId, $active = true) return $shippingMethod; } + /** + * Retrieves shipping service details. + * + * @param int $id + * @param string $carrierName + * @param string $fromCountry + * @param string $toCountry + * @param bool $originDropOff + * @param bool $destinationDropOff + * @param float $basePrice + * + * @return \Packlink\BusinessLogic\Http\DTO\BaseDto|\Packlink\BusinessLogic\Http\DTO\ShippingServiceDetails + */ private function getShippingServiceDetails( $id, $carrierName, @@ -876,6 +923,13 @@ private function getShippingServiceDetails( return $details; } + /** + * Retrieves invalid response. + * + * @param int $number + * + * @return array + */ private function getBadHttpResponses($number) { $responses = array(); @@ -886,6 +940,11 @@ private function getBadHttpResponses($number) return $responses; } + /** + * Retrieves parcel with wrong parameters. + * + * @return array + */ public function wrongParametersProvider() { return array( diff --git a/tests/BusinessLogic/Tasks/SendDraftTaskTest.php b/tests/BusinessLogic/Tasks/SendDraftTaskTest.php index 16a3089a..c3c0c8a6 100644 --- a/tests/BusinessLogic/Tasks/SendDraftTaskTest.php +++ b/tests/BusinessLogic/Tasks/SendDraftTaskTest.php @@ -4,9 +4,13 @@ use Logeecom\Infrastructure\Http\HttpClient; use Logeecom\Infrastructure\Http\HttpResponse; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Task; use Logeecom\Tests\BusinessLogic\BaseSyncTest; use Logeecom\Tests\BusinessLogic\Common\TestComponents\Order\TestOrderRepository; +use Logeecom\Tests\Infrastructure\Common\TestComponents\ORM\MemoryRepository; +use Logeecom\Tests\Infrastructure\Common\TestComponents\ORM\TestRepositoryRegistry; use Logeecom\Tests\Infrastructure\Common\TestComponents\TestHttpClient; use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use Packlink\BusinessLogic\Http\DTO\ParcelInfo; @@ -14,7 +18,9 @@ use Packlink\BusinessLogic\Http\DTO\Warehouse; use Packlink\BusinessLogic\Http\Proxy; use Packlink\BusinessLogic\Order\Interfaces\OrderRepository; +use Packlink\BusinessLogic\Order\Models\OrderShipmentDetails; use Packlink\BusinessLogic\Order\OrderService; +use Packlink\BusinessLogic\OrderShipmentDetails\OrderShipmentDetailsService; use Packlink\BusinessLogic\ShippingMethod\PackageTransformer; use Packlink\BusinessLogic\Tasks\SendDraftTask; @@ -47,6 +53,13 @@ function () use ($me) { } ); + TestServiceRegister::registerService( + OrderShipmentDetailsService::CLASS_NAME, + function () { + return OrderShipmentDetailsService::getInstance(); + } + ); + TestServiceRegister::registerService( OrderService::CLASS_NAME, function () { @@ -78,6 +91,18 @@ function () use ($orderRepository) { } ); + TestServiceRegister::registerService( + Serializer::CLASS_NAME, + function() { + return new NativeSerializer(); + } + ); + + TestRepositoryRegistry::registerRepository( + OrderShipmentDetails::getClassName(), + MemoryRepository::getClassName() + ); + $this->shopConfig->setDefaultParcel(new ParcelInfo()); $this->shopConfig->setDefaultWarehouse(new Warehouse()); $this->shopConfig->setUserInfo(new User()); @@ -97,6 +122,7 @@ protected function tearDown() * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpCommunicationException * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpRequestException * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException */ public function testExecute() { @@ -117,6 +143,7 @@ public function testExecute() * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpCommunicationException * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpRequestException * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException */ public function testExecuteBadResponse() { @@ -129,6 +156,7 @@ public function testExecuteBadResponse() * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpCommunicationException * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpRequestException * @throws \Packlink\BusinessLogic\Order\Exceptions\OrderNotFound + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException */ public function testAfterFailure() { @@ -139,13 +167,13 @@ public function testAfterFailure() try { $this->syncTask->execute(); } catch (\Exception $e) { - $serialized = serialize($this->syncTask); + $serialized = Serializer::serialize($this->syncTask); } $this->httpClient->setMockResponses($this->getMockResponses()); $orderRepository->shouldThrowOrderNotFoundException(false); /** @var SendDraftTask $task */ - $task = unserialize($serialized); + $task = Serializer::unserialize($serialized); $task->execute(); $order = $orderRepository->getOrder('test'); diff --git a/tests/BusinessLogic/Tasks/UpdateShipmentDataTaskTest.php b/tests/BusinessLogic/Tasks/UpdateShipmentDataTaskTest.php index f878fad5..3466cb57 100644 --- a/tests/BusinessLogic/Tasks/UpdateShipmentDataTaskTest.php +++ b/tests/BusinessLogic/Tasks/UpdateShipmentDataTaskTest.php @@ -4,6 +4,7 @@ use Logeecom\Infrastructure\Http\HttpClient; use Logeecom\Infrastructure\Http\HttpResponse; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Tests\BusinessLogic\BaseSyncTest; use Logeecom\Tests\BusinessLogic\Common\TestComponents\Order\TestOrderRepository; use Logeecom\Tests\Infrastructure\Common\TestComponents\TestHttpClient; @@ -18,6 +19,11 @@ use Packlink\BusinessLogic\ShippingMethod\Utility\ShipmentStatus; use Packlink\BusinessLogic\Tasks\UpdateShipmentDataTask; +/** + * Class UpdateShipmentDataTaskTest + * + * @package Logeecom\Tests\BusinessLogic\Tasks + */ class UpdateShipmentDataTaskTest extends BaseSyncTest { /** @@ -127,13 +133,13 @@ public function testAfterInitialFailure() try { $this->syncTask->execute(); } catch (\Exception $e) { - $serialized = serialize($this->syncTask); + $serialized = Serializer::serialize($this->syncTask); } $this->httpClient->setMockResponses($this->getMockResponses()); $orderRepository->shouldThrowGenericException(false); - $this->syncTask = unserialize($serialized); + $this->syncTask = Serializer::unserialize($serialized); $this->attachProgressEventListener(); $this->syncTask->execute(); $this->validate100Progress(); @@ -163,7 +169,7 @@ public function testAfterOrderNotFoundFailure() // second execute of the same task should not do anything after unserialize // because references that are done should be removed from the list - $this->syncTask = unserialize(serialize($this->syncTask)); + $this->syncTask = Serializer::unserialize(Serializer::serialize($this->syncTask)); $this->attachProgressEventListener(); $this->syncTask->execute(); $this->validate100Progress(); @@ -186,8 +192,7 @@ public function testAfterProxyFailure() } self::assertNotEmpty($e); - self::assertCount(1, $this->shopLogger->loggedMessages); - self::assertEquals('No response', $this->shopLogger->loggedMessages[0]->getMessage()); + self::assertCount(0, $this->shopLogger->loggedMessages); self::assertCount(2, $this->eventHistory); /** @var \Logeecom\Infrastructure\TaskExecution\TaskEvents\TaskProgressEvent $event */ $event = $this->eventHistory[0]; @@ -195,7 +200,7 @@ public function testAfterProxyFailure() self::assertEquals(500, $event->getProgressBasePoints()); // second execute of the same task should take only the third reference and execute it correctly - $this->syncTask = unserialize(serialize($this->syncTask)); + $this->syncTask = Serializer::unserialize(Serializer::serialize($this->syncTask)); $this->attachProgressEventListener(); $this->httpClient->setMockResponses( @@ -218,7 +223,7 @@ public function testAfterProxyFailure() self::assertCount(4, $this->eventHistory); // no new messages - self::assertCount(1, $this->shopLogger->loggedMessages); + self::assertCount(0, $this->shopLogger->loggedMessages); $this->validate100Progress(); } @@ -249,6 +254,20 @@ public function testShipmentStatus() self::assertEquals(ShipmentStatus::STATUS_DELIVERED, ShipmentStatus::getStatus('RETURNED_TO_SENDER')); } + /** + * Tests execute with order statuses provided. + * + * @throws \Logeecom\Infrastructure\Http\Exceptions\HttpBaseException + */ + public function testWithOrderStatusesProvided() + { + $this->syncTask = new UpdateShipmentDataTask(array(ShipmentStatus::STATUS_IN_TRANSIT)); + $this->attachProgressEventListener(); + $this->httpClient->setMockResponses($this->getMockResponses()); + $this->syncTask->execute(); + self::assertCount(3, $this->eventHistory); + } + /** * Creates new instance of task that is being tested. * diff --git a/tests/BusinessLogic/WebHook/WebHookHandlerTest.php b/tests/BusinessLogic/WebHook/WebHookHandlerTest.php index 82883066..213d8646 100644 --- a/tests/BusinessLogic/WebHook/WebHookHandlerTest.php +++ b/tests/BusinessLogic/WebHook/WebHookHandlerTest.php @@ -73,63 +73,6 @@ protected function tearDown() parent::tearDown(); } - /** - * Tests setting of shipment labels - */ - public function testHandleShipmentLabelEvent() - { - $this->httpClient->setMockResponses($this->getMockLabelResponse()); - $webhookHandler = WebHookEventHandler::getInstance(); - $input = $this->getShipmentLabelEventBody(); - $webhookHandler->handle($input); - - /** @var TestOrderRepository $orderRepository */ - $orderRepository = ServiceRegister::getService(OrderRepository::CLASS_NAME); - $order = $orderRepository->getOrder('test'); - - $this->assertNotNull($order); - $this->assertNotEmpty($order->getPacklinkShipmentLabels()); - $this->assertCount(1, $order->getPacklinkShipmentLabels()); - } - - /** - * Tests when API fails - */ - public function testHandleShipmentLabelEventHttpError() - { - $this->httpClient->setMockResponses($this->getErrorMockResponse()); - $webhookHandler = WebHookEventHandler::getInstance(); - $input = $this->getShipmentLabelEventBody(); - $webhookHandler->handle($input); - - $this->assertNotEmpty($this->shopLogger->loggedMessages); - /** @var \Logeecom\Infrastructure\Logger\LogData $logData */ - $logData = end($this->shopLogger->loggedMessages); - $this->assertNotEmpty($logData); - $logContextData = $logData->getContext(); - $this->assertNotEmpty($logContextData); - $this->assertEquals('referenceId', $logContextData[0]->getName()); - $this->assertEquals('test', $logContextData[0]->getValue()); - } - - /** - * Tests when order fetch fails - */ - public function testHandleShipmentLabelEventNoOrder() - { - /** @var TestOrderRepository $orderRepository */ - $orderRepository = ServiceRegister::getService(OrderRepository::CLASS_NAME); - $orderRepository->shouldThrowOrderNotFoundException(true); - - $this->httpClient->setMockResponses($this->getMockLabelResponse()); - $webhookHandler = WebHookEventHandler::getInstance(); - $input = $this->getShipmentLabelEventBody(); - $webhookHandler->handle($input); - - $this->assertNotEmpty($this->shopLogger->loggedMessages); - $this->assertEquals('Order not found.', $this->shopLogger->loggedMessages[1]->getMessage()); - } - /** * Tests setting of shipping status */ diff --git a/tests/Infrastructure/Common/BaseInfrastructureTestWithServices.php b/tests/Infrastructure/Common/BaseInfrastructureTestWithServices.php index eab889f1..b92a8bd2 100644 --- a/tests/Infrastructure/Common/BaseInfrastructureTestWithServices.php +++ b/tests/Infrastructure/Common/BaseInfrastructureTestWithServices.php @@ -10,6 +10,8 @@ use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\Logger\LoggerConfiguration; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\Utility\Events\EventBus; use Logeecom\Infrastructure\Utility\TimeProvider; use Logeecom\Tests\Infrastructure\Common\TestComponents\Logger\TestDefaultLogger; @@ -48,6 +50,10 @@ abstract class BaseInfrastructureTestWithServices extends TestCase * @var array */ public $eventHistory; + /** + * @var \Logeecom\Infrastructure\Serializer\Serializer + */ + public $serializer; /** * @throws \Exception @@ -63,6 +69,7 @@ protected function setUp() $this->shopConfig = new TestShopConfiguration(); $this->shopLogger = new TestShopLogger(); $this->defaultLogger = new TestDefaultLogger(); + $this->serializer = new NativeSerializer(); new TestServiceRegister( array( @@ -81,6 +88,9 @@ protected function setUp() EventBus::CLASS_NAME => function () { return EventBus::getInstance(); }, + Serializer::CLASS_NAME => function () use ($me) { + return $me->serializer; + } ) ); } diff --git a/tests/Infrastructure/Common/TestComponents/ORM/MemoryRepository.php b/tests/Infrastructure/Common/TestComponents/ORM/MemoryRepository.php index 5636fddf..667e162c 100644 --- a/tests/Infrastructure/Common/TestComponents/ORM/MemoryRepository.php +++ b/tests/Infrastructure/Common/TestComponents/ORM/MemoryRepository.php @@ -64,6 +64,10 @@ function ($a) use ($type) { $result = array_merge($result, $groupResult); } + if (is_array($result) && !empty($result)) { + $result = $this->unique($result); + } + if ($filter) { $this->sortResults($result, $filter, $fieldIndexMap); $result = $this->sliceResults($filter, $result); @@ -159,9 +163,18 @@ public function setEntityClass($entityClass) $this->entityClass = $entityClass; } + /** + * Saves entity to the database. + * + * @param \Logeecom\Infrastructure\ORM\Entity $entity Entity to be saved + */ private function saveEntityToStorage(Entity $entity) { $indexes = IndexHelper::transformFieldsToIndexes($entity); + $data = $entity->toArray(); + $data['class_name'] = $entity::getClassName(); + $data = json_encode($data); + $storageItem = array( 'id' => $entity->getId(), 'type' => $entity->getConfig()->getType(), @@ -175,7 +188,7 @@ private function saveEntityToStorage(Entity $entity) 'index_8' => null, 'index_9' => null, 'index_10' => null, - 'data' => serialize($entity), + 'data' => $data, ); foreach ($indexes as $index => $value) { @@ -368,6 +381,29 @@ private function translateToEntities(array $result) return $translator->translate($intermediates); } + /** + * Removes duplicate values from an array. + * + * @param array $array + * + * @return array + */ + private function unique(array $array) + { + $result = array(); + $occurrences = array(); + + foreach ($array as $item) { + $fingerprint = md5(serialize($item)); + if (!in_array($fingerprint, $occurrences, true)) { + $result[] = $item; + $occurrences[] = $fingerprint; + } + } + + return $result; + } + /** * Counts records that match filter criteria. * diff --git a/tests/Infrastructure/Common/TestComponents/TaskExecution/FooTask.php b/tests/Infrastructure/Common/TestComponents/TaskExecution/FooTask.php index 0658a4d7..86b05246 100644 --- a/tests/Infrastructure/Common/TestComponents/TaskExecution/FooTask.php +++ b/tests/Infrastructure/Common/TestComponents/TaskExecution/FooTask.php @@ -2,8 +2,14 @@ namespace Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Task; +/** + * Class FooTask + * + * @package Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution + */ class FooTask extends Task { private $dependency1; @@ -19,6 +25,39 @@ public function __construct($dependency1 = '', $dependency2 = 0) $this->dependency2 = $dependency2; } + /** + * Transforms array into an serializable object, + * + * @param array $array Data that is used to instantiate serializable object. + * + * @return \Logeecom\Infrastructure\Serializer\Interfaces\Serializable + * Instance of serialized object. + */ + public static function fromArray(array $array) + { + $entity = new static(); + + $entity->dependency1 = $array['dependency_1']; + $entity->dependency2 = $array['dependency_2']; + $entity->methodsCallCount = $array['method_call_count']; + + return $entity; + } + + /** + * Transforms serializable object into an array. + * + * @return array Array representation of a serializable object. + */ + public function toArray() + { + return array( + 'dependency_1' => $this->dependency1, + 'dependency_2' => $this->dependency2, + 'method_call_count' => $this->methodsCallCount, + ); + } + /** * String representation of object * @@ -26,11 +65,11 @@ public function __construct($dependency1 = '', $dependency2 = 0) */ public function serialize() { - return serialize( + return Serializer::serialize( array( 'dependency1' => $this->dependency1, 'dependency2' => $this->dependency2, - 'methodsCallCount' => serialize($this->methodsCallCount), + 'methodsCallCount' => Serializer::serialize($this->methodsCallCount), ) ); } @@ -46,10 +85,10 @@ public function serialize() */ public function unserialize($serialized) { - $data = unserialize($serialized); + $data = Serializer::unserialize($serialized); $this->dependency1 = $data['dependency1']; $this->dependency2 = $data['dependency2']; - $this->methodsCallCount = unserialize($data['methodsCallCount']); + $this->methodsCallCount = Serializer::unserialize($data['methodsCallCount']); } public function execute() diff --git a/tests/Infrastructure/ORM/AbstractGenericQueueItemRepositoryTest.php b/tests/Infrastructure/ORM/AbstractGenericQueueItemRepositoryTest.php index 1a5d37ab..1a9b2247 100644 --- a/tests/Infrastructure/ORM/AbstractGenericQueueItemRepositoryTest.php +++ b/tests/Infrastructure/ORM/AbstractGenericQueueItemRepositoryTest.php @@ -4,6 +4,7 @@ use Logeecom\Infrastructure\ORM\QueryFilter\QueryFilter; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\BarTask; use Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\FooTask; @@ -307,7 +308,7 @@ protected function readQueueItemsFromFile() $queueItem->setLastExecutionProgressBasePoints($item['lastExecutionProgress']); $queueItem->setRetries($item['retries']); $queueItem->setFailureDescription($item['failureDescription']); - $queueItem->setSerializedTask(serialize($task)); + $queueItem->setSerializedTask(Serializer::serialize($task)); $queueItem->setCreateTimestamp($item['createTimestamp']); $queueItem->setQueueTimestamp($item['queueTimestamp']); $queueItem->setStartTimestamp($item['startTimestamp']); diff --git a/tests/Infrastructure/ORM/AbstractGenericStudentRepositoryTest.php b/tests/Infrastructure/ORM/AbstractGenericStudentRepositoryTest.php index 49a0f044..0f054d4f 100644 --- a/tests/Infrastructure/ORM/AbstractGenericStudentRepositoryTest.php +++ b/tests/Infrastructure/ORM/AbstractGenericStudentRepositoryTest.php @@ -193,6 +193,315 @@ public function testQueryWithAndAndOr() $this->assertEquals(5, $student->localId); } + /** + * Tests repository implementation with NOT_EQUALS operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithNotEquals() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $count = count($this->readStudentsFromFile()); + + $query = new QueryFilter(); + $query->where('localId', Operators::NOT_EQUALS, 4); + + $students = $repository->select($query); + $this->assertCount($count - 1, $students); + + $query->where('localId', Operators::EQUALS, 4); + + $students = $repository->select($query); + $this->assertCount(0, $students); + + $query = new QueryFilter(); + $query->where('localId', Operators::NOT_EQUALS, 4); + $query->orWhere('localId', Operators::NOT_EQUALS, 7); + + $students = $repository->select($query); + $this->assertCount($count, $students); + + $query = new QueryFilter(); + $query->where('localId', Operators::NOT_EQUALS, 4); + $query->where('localId', Operators::NOT_EQUALS, 7); + + $students = $repository->select($query); + $this->assertCount($count - 2, $students); + } + + /** + * Test base repository with GREATER_THAN operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithGreaterThan() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::GREATER_THAN, 5); + + $students = $repository->select($query); + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThan(5, $student->localId); + } + + $query->where('localId', Operators::GREATER_THAN, 7); + $students = $repository->select($query); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThan(7, $student->localId); + } + + $query->orWhere('localId', Operators::GREATER_THAN, 4); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThan(4, $student->localId); + } + } + + /** + * Tests repository with LESS_THAN operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithLessThan() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::LESS_THAN, 7); + + $students = $repository->select($query); + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThan(7, $student->localId); + } + + $query->where('localId', Operators::LESS_THAN, 5); + $students = $repository->select($query); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThan(5, $student->localId); + } + + $query->orWhere('localId', Operators::LESS_THAN, 4); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThan(5, $student->localId); + } + } + + /** + * Tests repository with GREATER_THAN_OR_EQUAL_THAN operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithGreaterEqualThan() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::GREATER_OR_EQUAL_THAN, 5); + + $students = $repository->select($query); + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThanOrEqual(5, $student->localId); + } + + $query->where('localId', Operators::GREATER_OR_EQUAL_THAN, 7); + $students = $repository->select($query); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThanOrEqual(7, $student->localId); + } + + $query->orWhere('localId', Operators::GREATER_OR_EQUAL_THAN, 4); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertGreaterThanOrEqual(4, $student->localId); + } + } + + /** + * Tests repository with LEST_OR_EQUAL_THAN_OPERATOR + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithLessOrEqualThan() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::LESS_OR_EQUAL_THAN, 7); + + $students = $repository->select($query); + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThanOrEqual(7, $student->localId); + } + + $query->where('localId', Operators::LESS_OR_EQUAL_THAN, 5); + $students = $repository->select($query); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThanOrEqual(5, $student->localId); + } + + $query->orWhere('localId', Operators::LESS_OR_EQUAL_THAN, 4); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThanOrEqual(5, $student->localId); + } + } + + /** + * Test repository with combined comparison operators. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithCombinedComparisonOperators() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::LESS_OR_EQUAL_THAN, 7); + $query->where('localId', Operators::GREATER_THAN, 4); + + $students = $repository->select($query); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertLessThanOrEqual(7, $student->localId); + $this->assertGreaterThan(4, $student->localId); + } + + $query = new QueryFilter(); + $query->where('localId', Operators::GREATER_THAN, 7); + $query->orWhere('localId', Operators::LESS_THAN, 5); + + $students = $repository->select($query); + foreach ($students as $student) { + $this->assertAttributeNotEquals(6, 'localId', $student); + } + } + + /** + * Tests repository with IN operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithInOperator() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $query = new QueryFilter(); + $query->where('localId', Operators::IN, array(5, 6, 7)); + + $students = $repository->select($query); + $this->assertCount(3, $students); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertContains($student->localId, array(5, 6, 7)); + } + + $query->where('localId', Operators::IN, array(5)); + $students = $repository->select($query); + $this->assertCount(1, $students); + $student = $students[0]; + $this->assertEquals(5, $student->localId); + + $query->orWhere('localId', Operators::IN, array(9)); + $students = $repository->select($query); + $this->assertCount(2, $students); + + $query->where('localId', Operators::IN, array(8)); + $students = $repository->select($query); + $this->assertCount(1, $students); + + $student = $students[0]; + $this->assertEquals(5, $student->localId); + } + + /** + * Tests repository with NOT_IN operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithNotInOperator() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $count = count($this->readStudentsFromFile()); + + $query = new QueryFilter(); + $query->where('localId', Operators::NOT_IN, array(5, 6, 7)); + + $students = $repository->select($query); + $this->assertCount($count - 3, $students); + + /** @var StudentEntity $student */ + foreach ($students as $student) { + $this->assertNotContains($student->localId, array(5, 6, 7)); + } + } + + /** + * Tests repository with LIKE operator. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException + */ + public function testQueryWithLikeOperator() + { + $repository = RepositoryRegistry::getRepository(StudentEntity::getClassName()); + $this->testStudentMassInsert(); + + $count = count($this->readStudentsFromFile()); + + $query = new QueryFilter(); + $query->where('username', Operators::LIKE, '%g1stu%'); + + $students = $repository->select($query); + + $this->assertCount($count, $students); + + $query->where('username', Operators::LIKE, '%9'); + $students = $repository->select($query); + $this->assertCount(1, $students); + /** @var StudentEntity $student */ + $student = $students[0]; + $this->assertStringEndsWith('9', $student->username); + } + /** * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException * @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException diff --git a/tests/Infrastructure/ORM/EntityTranslatorTest.php b/tests/Infrastructure/ORM/EntityTranslatorTest.php index 7421287c..1b3a8c27 100644 --- a/tests/Infrastructure/ORM/EntityTranslatorTest.php +++ b/tests/Infrastructure/ORM/EntityTranslatorTest.php @@ -4,6 +4,7 @@ use Logeecom\Infrastructure\ORM\IntermediateObject; use Logeecom\Infrastructure\ORM\Utility\EntityTranslator; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\TaskExecution\TaskRunnerStatus; use Logeecom\Tests\Infrastructure\Common\BaseInfrastructureTestWithServices; @@ -30,7 +31,10 @@ public function testTranslate() $entity->setFinishTimestamp(time()); $intermediate = new IntermediateObject(); - $intermediate->setData(serialize($entity)); + $data = $entity->toArray(); + $data['class_name'] = $entity::getClassName(); + $data = json_encode($data); + $intermediate->setData($data); $translator = new EntityTranslator(); $translator->init(QueueItem::getClassName()); @@ -66,7 +70,7 @@ public function testTranslateWrongEntity() $entity = new TaskRunnerStatus('Test', 123); $intermediate = new IntermediateObject(); - $intermediate->setData(serialize($entity)); + $intermediate->setData(Serializer::serialize($entity)); $translator = new EntityTranslator(); $translator->init(QueueItem::getClassName()); diff --git a/tests/Infrastructure/ORM/IntermediateObjectTest.php b/tests/Infrastructure/ORM/IntermediateObjectTest.php index b13bfe95..d8a298c4 100644 --- a/tests/Infrastructure/ORM/IntermediateObjectTest.php +++ b/tests/Infrastructure/ORM/IntermediateObjectTest.php @@ -3,6 +3,7 @@ namespace Logeecom\Tests\Infrastructure\ORM; use Logeecom\Infrastructure\ORM\IntermediateObject; +use Logeecom\Infrastructure\Serializer\Serializer; use PHPUnit\Framework\TestCase; /** @@ -48,7 +49,7 @@ public function testIndexesWrongIndex() public function testSetData() { - $data = serialize(array(1, 'a' => 5, 6)); + $data = Serializer::serialize(array(1, 'a' => 5, 6)); $object = new IntermediateObject(); $object->setData($data); $this->assertEquals($data, $object->getData()); diff --git a/tests/Infrastructure/ORM/RepositoryRegistryTest.php b/tests/Infrastructure/ORM/RepositoryRegistryTest.php index 08487e49..e37fa892 100644 --- a/tests/Infrastructure/ORM/RepositoryRegistryTest.php +++ b/tests/Infrastructure/ORM/RepositoryRegistryTest.php @@ -66,6 +66,18 @@ public function testGetQueueItemRepository() $this->assertInstanceOf(MemoryQueueItemRepository::getClassName(), $repository); } + /** + * Test isRegistered method. + * + * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryClassException + */ + public function testIsRegistered() + { + RepositoryRegistry::registerRepository('test', MemoryRepository::getClassName()); + $this->assertTrue(RepositoryRegistry::isRegistered('test')); + $this->assertFalse(RepositoryRegistry::isRegistered('test2')); + } + /** * @expectedException \Logeecom\Infrastructure\ORM\Exceptions\RepositoryClassException * @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException diff --git a/tests/Infrastructure/Serializer/JsonSerializerTest.php b/tests/Infrastructure/Serializer/JsonSerializerTest.php new file mode 100644 index 00000000..3f54deb7 --- /dev/null +++ b/tests/Infrastructure/Serializer/JsonSerializerTest.php @@ -0,0 +1,46 @@ +assertInstanceOf(get_class($task), $serialized); + $this->assertEquals($task->getDependency1(), $serialized->getDependency1()); + $this->assertEquals($task->getDependency2(), $serialized->getDependency2()); + $this->assertEquals($task->getMethodCallCount('execute'), $task->getMethodCallCount('execute')); + } + + public function testJsonArraySerialize() + { + $array = array(1, 2, 3, 4, 5); + $serialzied = Serializer::unserialize(Serializer::serialize($array)); + $this->assertCount(5, $serialzied); + } +} \ No newline at end of file diff --git a/tests/Infrastructure/Serializer/NativeSerializerTest.php b/tests/Infrastructure/Serializer/NativeSerializerTest.php new file mode 100644 index 00000000..f5e07826 --- /dev/null +++ b/tests/Infrastructure/Serializer/NativeSerializerTest.php @@ -0,0 +1,39 @@ +assertInstanceOf(get_class($task), $serialized); + $this->assertEquals($task->getDependency1(), $serialized->getDependency1()); + $this->assertEquals($task->getDependency2(), $serialized->getDependency2()); + $this->assertEquals($task->getMethodCallCount('execute'), $task->getMethodCallCount('execute')); + } +} \ No newline at end of file diff --git a/tests/Infrastructure/TaskExecution/ProcessEntityTest.php b/tests/Infrastructure/TaskExecution/ProcessEntityTest.php index 45784dc8..bec7031f 100644 --- a/tests/Infrastructure/TaskExecution/ProcessEntityTest.php +++ b/tests/Infrastructure/TaskExecution/ProcessEntityTest.php @@ -2,16 +2,17 @@ namespace Logeecom\Tests\Infrastructure\TaskExecution; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Process; use Logeecom\Infrastructure\TaskExecution\QueueItemStarter; -use PHPUnit\Framework\TestCase; +use Logeecom\Tests\Infrastructure\Common\BaseInfrastructureTestWithServices; /** * Class ProcessEntityTest. * * @package Logeecom\Tests\Infrastructure\TaskExecution */ -class ProcessEntityTest extends TestCase +class ProcessEntityTest extends BaseInfrastructureTestWithServices { public function testToArray() { @@ -25,7 +26,7 @@ public function testToArray() self::assertEquals($data['id'], $entity->getId()); self::assertEquals($data['guid'], $entity->getGuid()); - self::assertEquals($data['runner'], serialize($entity->getRunner())); + self::assertEquals($data['runner'], Serializer::serialize($entity->getRunner())); } public function testFromArrayAndToJSON() @@ -35,7 +36,7 @@ public function testFromArrayAndToJSON() 'class_name' => Process::CLASS_NAME, 'id' => 123, 'guid' => 'guid', - 'runner' => serialize($runner), + 'runner' => Serializer::serialize($runner), ); $entity = Process::fromArray($data); @@ -55,7 +56,7 @@ public function testFromArrayInvalidGuid() $runner = new QueueItemStarter(1234); $data = array( 'id' => 123, - 'runner' => serialize($runner), + 'runner' => Serializer::serialize($runner), ); Process::fromArray($data); diff --git a/tests/Infrastructure/TaskExecution/QueueItemEntityTest.php b/tests/Infrastructure/TaskExecution/QueueItemEntityTest.php index d7a71b3e..33c11721 100644 --- a/tests/Infrastructure/TaskExecution/QueueItemEntityTest.php +++ b/tests/Infrastructure/TaskExecution/QueueItemEntityTest.php @@ -2,6 +2,8 @@ namespace Logeecom\Tests\Infrastructure\TaskExecution; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\Utility\TimeProvider; use Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\FooTask; @@ -21,6 +23,8 @@ class QueueItemEntityTest extends TestCase */ protected $timeProvider; + protected $serializer; + /** * @throws \Exception */ @@ -29,12 +33,16 @@ protected function setUp() parent::setUp(); $timeProvider = $this->timeProvider = new TestTimeProvider(); + $serializer = $this->serializer = new NativeSerializer(); new TestServiceRegister( array( TimeProvider::CLASS_NAME => function () use ($timeProvider) { return $timeProvider; }, + Serializer::CLASS_NAME => function () use ($serializer) { + return $serializer; + } ) ); } @@ -57,7 +65,7 @@ public function testToArray() $entity->setId(1234); $entity->setStatus(QueueItem::COMPLETED); $entity->setContext('context'); - $entity->setSerializedTask(serialize(new FooTask())); + $entity->setSerializedTask(Serializer::serialize(new FooTask())); $entity->setQueueName('queue'); $entity->setLastExecutionProgressBasePoints(2541); $entity->setProgressBasePoints(458); @@ -122,7 +130,7 @@ public function testFromArrayAndToJSON() 'id' => 123, 'status' => QueueItem::COMPLETED, 'context' => 'context', - 'serializedTask' => serialize(new FooTask()), + 'serializedTask' => Serializer::serialize(new FooTask()), 'queueName' => 'queue', 'lastExecutionProgressBasePoints' => 1234, 'progressBasePoints' => 7345, diff --git a/tests/Infrastructure/TaskExecution/QueueItemStarterTest.php b/tests/Infrastructure/TaskExecution/QueueItemStarterTest.php index 302708fa..ad7a444e 100644 --- a/tests/Infrastructure/TaskExecution/QueueItemStarterTest.php +++ b/tests/Infrastructure/TaskExecution/QueueItemStarterTest.php @@ -10,6 +10,8 @@ use Logeecom\Infrastructure\Logger\Interfaces\ShopLoggerAdapter; use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Exceptions\QueueStorageUnavailableException; use Logeecom\Infrastructure\TaskExecution\Interfaces\TaskRunnerWakeup; use Logeecom\Infrastructure\TaskExecution\QueueItem; @@ -30,6 +32,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class QueueItemStarterTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class QueueItemStarterTest extends TestCase { /** @var \Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\TestQueueService */ @@ -56,6 +63,7 @@ public function setUp() $shopLogger = new TestShopLogger(); $shopConfiguration = new TestShopConfiguration(); $shopConfiguration->setIntegrationName('Shop1'); + $serializer = new NativeSerializer(); new TestServiceRegister( array( @@ -83,6 +91,9 @@ public function setUp() HttpClient::CLASS_NAME => function () { return new TestHttpClient(); }, + Serializer::CLASS_NAME => function () use ($serializer) { + return $serializer; + } ) ); @@ -139,7 +150,7 @@ public function testItemStarterMustBeRunnableAfterDeserialization() ); $itemStarter = new QueueItemStarter($queueItem->getId()); /** @var QueueItemStarter $unserializedItemStarter */ - $unserializedItemStarter = unserialize(serialize($itemStarter)); + $unserializedItemStarter = Serializer::unserialize(Serializer::serialize($itemStarter)); // Act $unserializedItemStarter->run(); diff --git a/tests/Infrastructure/TaskExecution/QueueItemTest.php b/tests/Infrastructure/TaskExecution/QueueItemTest.php index 54eb7ab8..9da592a7 100644 --- a/tests/Infrastructure/TaskExecution/QueueItemTest.php +++ b/tests/Infrastructure/TaskExecution/QueueItemTest.php @@ -2,6 +2,8 @@ namespace Logeecom\Tests\Infrastructure\TaskExecution; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\Utility\TimeProvider; use Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\FooTask; @@ -9,6 +11,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class QueueItemTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class QueueItemTest extends TestCase { /** @var \Logeecom\Tests\Infrastructure\Common\TestComponents\Utility\TestTimeProvider */ @@ -26,6 +33,9 @@ protected function setUp() TimeProvider::CLASS_NAME => function () use ($timeProvider) { return $timeProvider; }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); @@ -69,7 +79,7 @@ public function testWhenQueueItemIsCreatedItShouldBeInCreatedStatus() 'When created queue item must set failure description to empty string.' ); $this->assertEquals( - serialize($task), + Serializer::serialize($task), $queueItem->getSerializedTask(), 'When created queue item must record given task.' ); @@ -96,7 +106,7 @@ public function testItShouldBePossibleToCreateQueueItemWithSerializedTask() $task = new FooTask('test task', 123); $queueItem = new QueueItem(); - $queueItem->setSerializedTask(serialize($task)); + $queueItem->setSerializedTask(Serializer::serialize($task)); /** @var FooTask $actualTask */ $actualTask = $queueItem->getTask(); @@ -128,7 +138,7 @@ public function testItShouldUpdateTaskWhenSettingSerializedTask() $newTask = new FooTask('new task', 123); $queueItem = new QueueItem(new FooTask('initial task', 1)); - $queueItem->setSerializedTask(serialize($newTask)); + $queueItem->setSerializedTask(Serializer::serialize($newTask)); /** @var \Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\FooTask $actualTask */ $actualTask = $queueItem->getTask(); @@ -268,7 +278,7 @@ public function testQueueItemIdToSerializedTask() $queueItem = new QueueItem(); $queueItem->setId(27); - $queueItem->setSerializedTask(serialize($task)); + $queueItem->setSerializedTask(Serializer::serialize($task)); /** @var \Logeecom\Tests\Infrastructure\Common\TestComponents\TaskExecution\FooTask $actualTask */ $actualTask = $queueItem->getTask(); diff --git a/tests/Infrastructure/TaskExecution/QueueTest.php b/tests/Infrastructure/TaskExecution/QueueTest.php index e5c38128..79cba8aa 100644 --- a/tests/Infrastructure/TaskExecution/QueueTest.php +++ b/tests/Infrastructure/TaskExecution/QueueTest.php @@ -7,6 +7,8 @@ use Logeecom\Infrastructure\Configuration\Configuration; use Logeecom\Infrastructure\ORM\QueryFilter\QueryFilter; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\Interfaces\TaskRunnerWakeup; use Logeecom\Infrastructure\TaskExecution\QueueItem; use Logeecom\Infrastructure\TaskExecution\QueueService; @@ -24,6 +26,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class QueueTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class QueueTest extends TestCase { /** @var QueueService */ @@ -60,6 +67,9 @@ public function setUp() EventBus::CLASS_NAME => function () { return EventBus::getInstance(); }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); @@ -1278,6 +1288,14 @@ private function generateRunningQueueItem($queueName, Task $task) return $queueItem; } + /** + * Checks whether queue item is in array. + * + * @param \Logeecom\Infrastructure\TaskExecution\QueueItem $needle + * @param array $haystack + * + * @return bool + */ private function inArrayQueueItem(QueueItem $needle, array $haystack) { /** @var QueueItem $queueItem */ diff --git a/tests/Infrastructure/TaskExecution/TaskRunnerStarterTest.php b/tests/Infrastructure/TaskExecution/TaskRunnerStarterTest.php index 93ff86ed..efa40de0 100644 --- a/tests/Infrastructure/TaskExecution/TaskRunnerStarterTest.php +++ b/tests/Infrastructure/TaskExecution/TaskRunnerStarterTest.php @@ -5,6 +5,7 @@ use Logeecom\Infrastructure\Http\HttpClient; use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\AsyncProcessStarterService; use Logeecom\Infrastructure\TaskExecution\Exceptions\TaskRunnerStatusStorageUnavailableException; use Logeecom\Infrastructure\TaskExecution\Interfaces\AsyncProcessService; @@ -25,6 +26,11 @@ use Logeecom\Tests\Infrastructure\Common\TestComponents\Utility\TestGuidProvider; use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; +/** + * Class TaskRunnerStarterTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class TaskRunnerStarterTest extends BaseInfrastructureTestWithServices { /** @var AsyncProcessService */ @@ -151,7 +157,7 @@ public function testTaskStarterMustBeRunnableAfterDeserialization() { // Arrange /** @var TaskRunnerStarter $unserializedRunnerStarter */ - $unserializedRunnerStarter = unserialize(serialize($this->runnerStarter)); + $unserializedRunnerStarter = Serializer::unserialize(Serializer::serialize($this->runnerStarter)); // Act $unserializedRunnerStarter->run(); diff --git a/tests/Infrastructure/TaskExecution/TaskRunnerTest.php b/tests/Infrastructure/TaskExecution/TaskRunnerTest.php index 982711e8..2c88f794 100644 --- a/tests/Infrastructure/TaskExecution/TaskRunnerTest.php +++ b/tests/Infrastructure/TaskExecution/TaskRunnerTest.php @@ -10,6 +10,8 @@ use Logeecom\Infrastructure\Logger\Interfaces\ShopLoggerAdapter; use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\AsyncProcessStarterService; use Logeecom\Infrastructure\TaskExecution\Interfaces\AsyncProcessService; use Logeecom\Infrastructure\TaskExecution\Interfaces\TaskRunnerStatusStorage; @@ -39,6 +41,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class TaskRunnerTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class TaskRunnerTest extends TestCase { /** @var AsyncProcessService */ @@ -115,6 +122,9 @@ protected function setUp() HttpClient::CLASS_NAME => function () { return new TestHttpClient(); }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); @@ -419,6 +429,14 @@ public function testRunWhenRunnerGuidIsNotSetAsLive() ); } + /** + * Checks wheter queue item is in call history. + * + * @param \Logeecom\Infrastructure\TaskExecution\QueueItem $needle + * @param array $callHistory + * + * @return bool + */ private function isQueueItemInStartCallHistory(QueueItem $needle, array $callHistory) { /** @var QueueItem $queueItem */ diff --git a/tests/Infrastructure/TaskExecution/TaskRunnerWakeupTest.php b/tests/Infrastructure/TaskExecution/TaskRunnerWakeupTest.php index 7f6e504d..3b1598a2 100644 --- a/tests/Infrastructure/TaskExecution/TaskRunnerWakeupTest.php +++ b/tests/Infrastructure/TaskExecution/TaskRunnerWakeupTest.php @@ -9,6 +9,8 @@ use Logeecom\Infrastructure\Logger\Interfaces\ShopLoggerAdapter; use Logeecom\Infrastructure\Logger\Logger; use Logeecom\Infrastructure\ORM\RepositoryRegistry; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\AsyncProcessStarterService; use Logeecom\Infrastructure\TaskExecution\Exceptions\TaskRunnerStatusChangeException; use Logeecom\Infrastructure\TaskExecution\Exceptions\TaskRunnerStatusStorageUnavailableException; @@ -32,6 +34,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class TaskRunnerWakeupTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class TaskRunnerWakeupTest extends TestCase { /** @var AsyncProcessService */ @@ -86,6 +93,9 @@ protected function setUp() HttpClient::CLASS_NAME => function () { return new TestHttpClient(); }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); diff --git a/tests/Infrastructure/TaskExecution/TaskTest.php b/tests/Infrastructure/TaskExecution/TaskTest.php index 88d299c6..4282c8cd 100644 --- a/tests/Infrastructure/TaskExecution/TaskTest.php +++ b/tests/Infrastructure/TaskExecution/TaskTest.php @@ -2,6 +2,8 @@ namespace Logeecom\Tests\Infrastructure\TaskExecution; +use Logeecom\Infrastructure\Serializer\Concrete\NativeSerializer; +use Logeecom\Infrastructure\Serializer\Serializer; use Logeecom\Infrastructure\TaskExecution\TaskEvents\AliveAnnouncedTaskEvent; use Logeecom\Infrastructure\TaskExecution\TaskEvents\TaskProgressEvent; use Logeecom\Infrastructure\Utility\TimeProvider; @@ -10,6 +12,11 @@ use Logeecom\Tests\Infrastructure\Common\TestServiceRegister; use PHPUnit\Framework\TestCase; +/** + * Class TaskTest + * + * @package Logeecom\Tests\Infrastructure\TaskExecution + */ class TaskTest extends TestCase { /** @var \Logeecom\Tests\Infrastructure\Common\TestComponents\Utility\TestTimeProvider */ @@ -27,6 +34,9 @@ protected function setUp() TimeProvider::CLASS_NAME => function () use ($timeProvider) { return $timeProvider; }, + Serializer::CLASS_NAME => function() { + return new NativeSerializer(); + } ) ); @@ -56,7 +66,7 @@ public function testItShouldBePossibleToSerializeTask() $task = new FooTask('test dependency', 123); /** @var FooTask $unserializedTask */ - $unserializedTask = unserialize(serialize($task)); + $unserializedTask = Serializer::unserialize(Serializer::serialize($task)); $this->assertInstanceOf('\Serializable', $unserializedTask); $this->assertSame('test dependency', $unserializedTask->getDependency1());