PluginProbe
Packeta / 2.1
Packeta v2.1
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
← All changes | tests/Module/Checkout/ShippingRateFactoryTest.php +569 -314 trunk2.1 View file →
@@ -3,370 +3,625 @@
3 3 declare( strict_types=1 );
4 4
5 5 namespace Tests\Module\Checkout;
6 6
7 -use Packetery\Core\Entity;
8 7 use Packetery\Module\Carrier;
9 8 use Packetery\Module\Carrier\CarDeliveryConfig;
9 +use Packetery\Module\Carrier\CarrierActivityBridge;
10 10 use Packetery\Module\Carrier\CarrierOptionsFactory;
11 -use Packetery\Module\Carrier\OptionPrefixer;
12 11 use Packetery\Module\Checkout\CartService;
13 12 use Packetery\Module\Checkout\CheckoutService;
14 -use Packetery\Module\Checkout\CurrencySwitcherService;
15 13 use Packetery\Module\Checkout\RateCalculator;
16 14 use Packetery\Module\Checkout\ShippingRateFactory;
17 -use Packetery\Module\DiagnosticsLogger\DiagnosticsLogger;
18 15 use Packetery\Module\Framework\WcAdapter;
16 +use Packetery\Module\Framework\WpAdapter;
19 17 use Packetery\Module\Options\OptionsProvider;
18 +use Packetery\Module\Product;
19 +use Packetery\Module\Product\ProductEntityFactory;
20 +use Packetery\Module\ProductCategory;
21 +use Packetery\Module\ProductCategory\ProductCategoryEntityFactory;
20 22 use Packetery\Module\Shipping\BaseShippingMethod;
23 +use Packetery\Module\Shipping\Generated\ShippingMethod_zpointcz;
21 24 use Packetery\Module\ShippingMethod;
22 25 use PHPUnit\Framework\MockObject\MockObject;
23 26 use PHPUnit\Framework\TestCase;
24 -use ReflectionMethod;
25 27 use Tests\Core\DummyFactory;
26 28 use Tests\Module\MockFactory;
29 +use WC_Cart;
30 +use WC_Product;
27 31
28 32 class ShippingRateFactoryTest extends TestCase {
29 - private const DUMMY_RATE_ID = 'dummyRateId';
30 33
31 - private CheckoutService&MockObject $checkoutServiceMock;
32 - private Carrier\EntityRepository&MockObject $carrierEntityRepositoryMock;
33 - private CartService&MockObject $cartServiceMock;
34 - private CarrierOptionsFactory&MockObject $carrierOptionsFactoryMock;
35 - private OptionsProvider&MockObject $optionsProviderMock;
36 - private DiagnosticsLogger&MockObject $diagnosticsLogger;
34 + private WpAdapter|MockObject $wpAdapter;
35 + private WcAdapter|MockObject $wcAdapter;
36 + private ProductEntityFactory|MockObject $productEntityFactory;
37 + private ProductCategoryEntityFactory|MockObject $productCategoryEntityFactory;
38 + private CarrierOptionsFactory|MockObject $carrierOptionsFactory;
39 + private WpAdapter|MockObject $currencySwitcherFacade;
40 + private Carrier\EntityRepository|MockObject $carrierEntityRepository;
41 + private CarDeliveryConfig|MockObject $carDeliveryConfig;
42 + private OptionsProvider|MockObject $provider;
43 + private CartService|MockObject $cartService;
44 + private CheckoutService|MockObject $checkoutService;
45 + private ShippingRateFactory $shippingRateFactory;
46 + private CarrierActivityBridge|MockObject $carrierActivityBridge;
37 47
38 - public function createShippingRateFactory(): ShippingRateFactory {
39 - $wpAdapterMock = MockFactory::createWpAdapter( $this );
40 - $wpAdapterMock->method( '__' )
41 - ->willReturnCallback(
42 - function ( string $text ): string {
43 - return $text;
44 - }
45 - );
46 -
47 - $wcAdapterMock = $this->createMock( WcAdapter::class );
48 - $this->checkoutServiceMock = $this->createMock( CheckoutService::class );
49 - $this->carrierEntityRepositoryMock = $this->createMock( Carrier\EntityRepository::class );
50 - $this->cartServiceMock = $this->createMock( CartService::class );
51 - $this->carrierOptionsFactoryMock = $this->createMock( CarrierOptionsFactory::class );
52 - $this->optionsProviderMock = $this->createMock( OptionsProvider::class );
53 - $this->diagnosticsLogger = $this->createMock( DiagnosticsLogger::class );
54 -
55 - $rateCalculator = new RateCalculator(
56 - $wpAdapterMock,
57 - $wcAdapterMock,
58 - $this->createMock( CurrencySwitcherService::class ),
59 - $this->diagnosticsLogger
60 - );
61 -
62 - return new ShippingRateFactory(
63 - $wpAdapterMock,
64 - $wcAdapterMock,
65 - $this->checkoutServiceMock,
66 - $this->carrierEntityRepositoryMock,
67 - $this->cartServiceMock,
68 - $this->carrierOptionsFactoryMock,
69 - $this->createMock( CarDeliveryConfig::class ),
70 - $rateCalculator,
71 - $this->optionsProviderMock,
72 - $this->diagnosticsLogger
73 - );
74 - }
75 -
76 - public static function createShippingRateAndApplyTaxesProvider(): array {
48 + /**
49 + * @return array
50 + */
51 + private static function createDummyZpointCzCarrierOptions(): array {
77 52 return [
78 - 'free shipping label appended when cost zero and visibility on' => [
79 - 'cost' => 0.0,
80 - 'isFreeShippingShown' => true,
81 - 'expectedLabel' => 'Carrier Name: Free',
82 - 'arePricesTaxInclusive' => false,
83 - ],
84 - 'free shipping label not appended when cost zero and visibility off' => [
85 - 'cost' => 0.0,
86 - 'isFreeShippingShown' => false,
87 - 'expectedLabel' => 'Carrier Name',
88 - 'arePricesTaxInclusive' => false,
89 - ],
90 - 'positive cost keeps label unchanged' => [
91 - 'cost' => 123.45,
92 - 'isFreeShippingShown' => true,
93 - 'expectedLabel' => 'Carrier Name',
94 - 'arePricesTaxInclusive' => false,
95 - ],
96 - 'apply taxes when prices are tax inclusive' => [
97 - 'cost' => 123.45,
98 - 'isFreeShippingShown' => true,
99 - 'expectedLabel' => 'Carrier Name',
100 - 'arePricesTaxInclusive' => true,
101 - ],
53 + 'id' => 'zpoint-cz',
54 + 'name' => 'zpoint-cz',
55 + 'active' => true,
56 + 'free_shipping_limit' => null,
57 + 'weight_limits' =>
58 + [
59 + [
60 + 'weight' => 20.0,
61 + 'price' => 234.34,
62 + ],
63 + ],
102 64 ];
103 65 }
104 66
105 - /**
106 - * @dataProvider createShippingRateAndApplyTaxesProvider
107 - */
108 - public function testCreateShippingRateAndApplyTaxes(
109 - float $cost,
110 - bool $isFreeShippingShown,
111 - string $expectedLabel,
112 - bool $arePricesTaxInclusive,
113 - ): void {
114 - $shippingRateFactory = $this->createShippingRateFactory();
67 + private function createShippingRateFactoryMock(): void {
68 + $this->wpAdapter = MockFactory::createWpAdapter( $this );
69 + $this->wcAdapter = $this->createMock( WcAdapter::class );
70 + $this->productEntityFactory = $this->createMock( ProductEntityFactory::class );
71 + $this->productCategoryEntityFactory = $this->createMock( ProductCategoryEntityFactory::class );
72 + $this->carrierOptionsFactory = $this->createMock( CarrierOptionsFactory::class );
73 + $this->currencySwitcherFacade = MockFactory::createCurrencySwitcherFacade( $this );
74 + $this->carrierEntityRepository = $this->createMock( Carrier\EntityRepository::class );
75 + $this->carDeliveryConfig = $this->createMock( CarDeliveryConfig::class );
76 + $this->provider = $this->createMock( OptionsProvider::class );
77 + $this->cartService = $this->createMock( CartService::class );
78 + $this->checkoutService = $this->createMock( CheckoutService::class );
79 + $this->carrierActivityBridge = $this->createMock( CarrierActivityBridge::class );
115 80
116 - $this->optionsProviderMock->method( 'isFreeShippingShown' )
117 - ->willReturn( $isFreeShippingShown );
118 - $this->optionsProviderMock->method( 'arePricesTaxInclusive' )
119 - ->willReturn( $arePricesTaxInclusive );
120 -
121 - $reflection = new ReflectionMethod( ShippingRateFactory::class, 'createShippingRateAndApplyTaxes' );
122 - $reflection->setAccessible( true );
123 - $resultRate = $reflection->invoke( $shippingRateFactory, 'Carrier Name', $cost, self::DUMMY_RATE_ID );
124 -
125 - self::assertIsArray( $resultRate );
126 - self::assertSame( $expectedLabel, $resultRate['label'] );
127 - self::assertSame( self::DUMMY_RATE_ID, $resultRate['id'] );
128 - self::assertSame( $cost, $resultRate['cost'] );
129 - self::assertSame( 'per_order', $resultRate['calc_tax'] );
81 + $this->shippingRateFactory = new ShippingRateFactory(
82 + $this->wpAdapter,
83 + $this->wcAdapter,
84 + $this->checkoutService,
85 + $this->carrierEntityRepository,
86 + $this->cartService,
87 + $this->carrierOptionsFactory,
88 + $this->carDeliveryConfig,
89 + new RateCalculator( $this->wpAdapter, $this->wcAdapter, $this->currencySwitcherFacade ),
90 + $this->provider,
91 + );
130 92 }
131 93
132 - public static function createShippingRatesProvider(): array {
133 - $carrierCzPp = DummyFactory::createCarrierCzechPp();
134 - $carrierCzHd = DummyFactory::createCarrierCzechHdRequiresSize();
135 - $carrierDe = DummyFactory::createCarrierGermanPp();
136 -
137 - $carrierOptionsCzPp = new Carrier\Options(
138 - OptionPrefixer::getOptionId( $carrierCzPp->getId() ),
139 - [
140 - 'id' => $carrierCzPp->getId(),
141 - 'active' => true,
142 - 'name' => 'Carrier CZ I',
143 - 'weight_limits' => [
144 - [
145 - 'weight' => 5.0,
146 - 'price' => 30.0,
147 - ],
94 + public static function rateCreationDataProvider(): array {
95 + return [
96 + 'configured carriers must be present in rates' =>
97 + [
98 + 'expectedRateCount' => 2,
99 + 'carriers' =>
100 + [
101 + DummyFactory::createCarrierCzechPp(),
102 + DummyFactory::createCarrierCzechHdRequiresSize(),
103 + ],
104 + 'carriersOptions' =>
105 + [
106 + 'packetery_carrier_zpoint-cz' =>
107 + self::createDummyZpointCzCarrierOptions(),
108 + 'packetery_carrier_106' =>
109 + [
110 + 'id' => '106',
111 + 'name' => 'hd-cz',
112 + 'active' => true,
113 + 'free_shipping_limit' => null,
114 + 'weight_limits' =>
115 + [
116 + [
117 + 'weight' => 5.0,
118 + 'price' => 444.34,
119 + ],
120 + ],
121 + ],
122 + ],
123 + 'productDisallowedRateIds' => [],
124 + 'productCategoryDisallowedRateIds' => [],
125 + 'allowedCarrierNames' =>
126 + [
127 + 'zpoint-cz' => 'zpoint-cz',
128 + 106 => 'hd-cz',
129 + ],
130 + 'isCarDeliveryEnabled' => true,
131 + 'isAgeVerificationRequiredByProduct' => false,
132 + 'cartWeightKg' => 5.0,
133 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
148 134 ],
149 - 'free_shipping_limit' => null,
150 - ],
151 - );
152 - $carrierOptionsCzHd = new Carrier\Options(
153 - OptionPrefixer::getOptionId( $carrierCzHd->getId() ),
154 - [
155 - 'id' => $carrierCzHd->getId(),
156 - 'active' => true,
157 - 'name' => 'Carrier CZ II',
158 - 'weight_limits' => null,
159 - 'product_value_limits' => [
160 - [
161 - 'value' => 0.0,
162 - 'price' => 30.0,
163 - ],
164 - [
165 - 'value' => 2000.0,
166 - 'price' => 25.0,
167 - ],
135 + 'new style carrier' =>
136 + [
137 + 'expectedRateCount' => 1,
138 + 'carriers' =>
139 + [
140 + DummyFactory::createCarrierCzechPp(),
141 + ],
142 + 'carriersOptions' =>
143 + [
144 + 'packetery_carrier_zpoint-cz' =>
145 + self::createDummyZpointCzCarrierOptions(),
146 + ],
147 + 'productDisallowedRateIds' => [],
148 + 'productCategoryDisallowedRateIds' => [],
149 + 'allowedCarrierNames' =>
150 + [
151 + 'zpoint-cz' => 'zpoint-cz',
152 + ],
153 + 'isCarDeliveryEnabled' => true,
154 + 'isAgeVerificationRequiredByProduct' => false,
155 + 'cartWeightKg' => 5.0,
156 + 'shippingMethod' => BaseShippingMethod::PACKETA_METHOD_PREFIX . ShippingMethod_zpointcz::CARRIER_ID,
168 157 ],
169 - 'free_shipping_limit' => null,
170 - 'pricing_type' => 'byProductValue',
171 - ],
172 - );
173 - $carrierOptionsDe = new Carrier\Options(
174 - OptionPrefixer::getOptionId( $carrierDe->getId() ),
175 - [
176 - 'id' => $carrierDe->getId(),
177 - 'active' => true,
178 - 'name' => 'Carrier DE',
179 - 'weight_limits' => [
180 - [
181 - 'weight' => 5.0,
182 - 'price' => 30.0,
183 - ],
158 + 'new style carrier country mismatch' =>
159 + [
160 + 'expectedRateCount' => 0,
161 + 'carriers' =>
162 + [
163 + DummyFactory::createCarrierSlovakPp(),
164 + ],
165 + 'carriersOptions' =>
166 + [
167 + 'packetery_carrier_zpoint-sk' =>
168 + [
169 + 'id' => 'zpoint-sk',
170 + 'name' => 'zpoint-sk',
171 + 'active' => true,
172 + 'free_shipping_limit' => null,
173 + 'weight_limits' =>
174 + [
175 + [
176 + 'weight' => 20.0,
177 + 'price' => 234.34,
178 + ],
179 + ],
180 + ],
181 + ],
182 + 'productDisallowedRateIds' => [],
183 + 'productCategoryDisallowedRateIds' => [],
184 + 'allowedCarrierNames' =>
185 + [
186 + 'zpoint-cz' => 'zpoint-cz',
187 + ],
188 + 'isCarDeliveryEnabled' => true,
189 + 'isAgeVerificationRequiredByProduct' => false,
190 + 'cartWeightKg' => 5.0,
191 + 'shippingMethod' => BaseShippingMethod::PACKETA_METHOD_PREFIX . ShippingMethod_zpointcz::CARRIER_ID,
184 192 ],
185 - 'free_shipping_limit' => 90.0,
186 - ],
187 - );
188 -
189 - return [
190 - 'no customer country -> empty result' => [
191 - 'allowedCarrierNames' => null,
192 - 'methodId' => ShippingMethod::PACKETERY_METHOD_ID,
193 - 'instanceId' => 1,
194 - 'customerCountry' => null,
195 - 'availableCarriers' => [],
196 - 'cartTotal' => 100.0,
197 - 'cartWeight' => 1.0,
198 - 'totalValue' => 100.0,
199 - 'isAgeVerificationRequired' => false,
200 - 'disallowedRateIds' => [],
201 - 'oversized' => false,
202 - 'restrictedByCategory' => false,
203 - 'arePricesTaxInclusive' => false,
204 - 'rateCost' => 10.0,
205 - 'expectedRateCount' => 0,
206 - ],
207 - 'packetery method with 2 carriers in same country' => [
208 - 'allowedCarrierNames' => null,
209 - 'methodId' => ShippingMethod::PACKETERY_METHOD_ID,
210 - 'instanceId' => 1,
211 - 'customerCountry' => 'cz',
212 - 'availableCarriers' => [ [ $carrierCzPp, $carrierOptionsCzPp ], [ $carrierCzHd, $carrierOptionsCzHd ] ],
213 - 'cartTotal' => 100.0,
214 - 'cartWeight' => 1.0,
215 - 'totalValue' => 100.0,
216 - 'isAgeVerificationRequired' => false,
217 - 'disallowedRateIds' => [],
218 - 'oversized' => false,
219 - 'restrictedByCategory' => false,
220 - 'arePricesTaxInclusive' => false,
221 - 'rateCost' => 10.0,
222 - 'expectedRateCount' => 2,
223 - ],
224 - 'specific carrier method with matching country' => [
225 - 'allowedCarrierNames' => null,
226 - 'methodId' => BaseShippingMethod::PACKETA_METHOD_PREFIX . $carrierDe->getId(),
227 - 'instanceId' => 7,
228 - 'customerCountry' => 'de',
229 - 'availableCarriers' => [ [ $carrierDe, $carrierOptionsDe ], [ $carrierCzPp, $carrierOptionsCzPp ] ],
230 - 'cartTotal' => 100.0,
231 - 'cartWeight' => 1.0,
232 - 'totalValue' => 100.0,
233 - 'isAgeVerificationRequired' => false,
234 - 'disallowedRateIds' => [],
235 - 'oversized' => false,
236 - 'restrictedByCategory' => false,
237 - 'arePricesTaxInclusive' => false,
238 - 'rateCost' => 10.0,
239 - 'expectedRateCount' => 1,
240 - ],
241 - 'specific carrier method with age verification not available' => [
242 - 'allowedCarrierNames' => null,
243 - 'methodId' => BaseShippingMethod::PACKETA_METHOD_PREFIX . $carrierDe->getId(),
244 - 'instanceId' => 7,
245 - 'customerCountry' => 'sk',
246 - 'availableCarriers' => [ [ $carrierDe, $carrierOptionsDe ] ],
247 - 'cartTotal' => 100.0,
248 - 'cartWeight' => 1.0,
249 - 'totalValue' => 100.0,
250 - 'isAgeVerificationRequired' => true,
251 - 'disallowedRateIds' => [],
252 - 'oversized' => false,
253 - 'restrictedByCategory' => false,
254 - 'arePricesTaxInclusive' => false,
255 - 'rateCost' => 10.0,
256 - 'expectedRateCount' => 0,
257 - ],
258 - 'specific carrier method with mismatched country' => [
259 - 'allowedCarrierNames' => null,
260 - 'methodId' => BaseShippingMethod::PACKETA_METHOD_PREFIX . $carrierDe->getId(),
261 - 'instanceId' => 7,
262 - 'customerCountry' => 'cz',
263 - 'availableCarriers' => [ [ $carrierDe, $carrierOptionsDe ] ],
264 - 'cartTotal' => 100.0,
265 - 'cartWeight' => 1.0,
266 - 'totalValue' => 100.0,
267 - 'isAgeVerificationRequired' => false,
268 - 'disallowedRateIds' => [],
269 - 'oversized' => false,
270 - 'restrictedByCategory' => false,
271 - 'arePricesTaxInclusive' => false,
272 - 'rateCost' => 10.0,
273 - 'expectedRateCount' => 0,
274 - ],
275 - 'allowedCarrierNames filter allows only one' => [
276 - 'allowedCarrierNames' => [ $carrierCzPp->getId() => 'Custom CZ' ],
277 - 'methodId' => ShippingMethod::PACKETERY_METHOD_ID,
278 - 'instanceId' => 1,
279 - 'customerCountry' => 'cz',
280 - 'availableCarriers' => [ [ $carrierCzPp, $carrierOptionsCzPp ], [ $carrierDe, $carrierOptionsDe ] ],
281 - 'cartTotal' => 100.0,
282 - 'cartWeight' => 1.0,
283 - 'totalValue' => 100.0,
284 - 'isAgeVerificationRequired' => false,
285 - 'disallowedRateIds' => [],
286 - 'oversized' => false,
287 - 'restrictedByCategory' => false,
288 - 'arePricesTaxInclusive' => false,
289 - 'rateCost' => 10.0,
290 - 'expectedRateCount' => 1,
291 - ],
193 + 'car delivery carrier must not be present in rates' =>
194 + [
195 + 'expectedRateCount' => 1,
196 + 'carriers' =>
197 + [
198 + DummyFactory::createCarrierCzechPp(),
199 + DummyFactory::createCarDeliveryCarrier(),
200 + ],
201 + 'carriersOptions' =>
202 + [
203 + 'packetery_carrier_zpoint-cz' =>
204 + self::createDummyZpointCzCarrierOptions(),
205 + 'packetery_carrier_25061' =>
206 + [
207 + 'id' => '25061',
208 + 'name' => 'CZ Zásilkovna do auta',
209 + 'active' => true,
210 + 'free_shipping_limit' => null,
211 + 'weight_limits' =>
212 + [
213 + [
214 + 'weight' => 5.0,
215 + 'price' => 444.34,
216 + ],
217 + ],
218 + ],
219 + ],
220 + 'productDisallowedRateIds' => [],
221 + 'productCategoryDisallowedRateIds' => [],
222 + 'allowedCarrierNames' => null,
223 + 'isCarDeliveryEnabled' => false,
224 + 'isAgeVerificationRequiredByProduct' => false,
225 + 'cartWeightKg' => 1.0,
226 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
227 + ],
228 + 'only one carrier is active' =>
229 + [
230 + 'expectedRateCount' => 1,
231 + 'carriers' =>
232 + [
233 + DummyFactory::createCarrierCzechPp(),
234 + DummyFactory::createCarrierCzechHdRequiresSize(),
235 + ],
236 + 'carriersOptions' =>
237 + [
238 + 'packetery_carrier_zpoint-cz' =>
239 + self::createDummyZpointCzCarrierOptions(),
240 + 'packetery_carrier_106' =>
241 + [
242 + 'id' => '106',
243 + 'name' => 'hd-cz',
244 + 'active' => false,
245 + 'free_shipping_limit' => null,
246 + 'weight_limits' =>
247 + [
248 + [
249 + 'weight' => 5.0,
250 + 'price' => 444.34,
251 + ],
252 + ],
253 + ],
254 + ],
255 + 'productDisallowedRateIds' => [],
256 + 'productCategoryDisallowedRateIds' => [],
257 + 'allowedCarrierNames' => null,
258 + 'isCarDeliveryEnabled' => true,
259 + 'isAgeVerificationRequiredByProduct' => false,
260 + 'cartWeightKg' => 1.0,
261 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
262 + ],
263 + 'carrier not supporting over-weight cart must be omitted' =>
264 + [
265 + 'expectedRateCount' => 0,
266 + 'carriers' =>
267 + [
268 + DummyFactory::createCarrierCzechPp(),
269 + ],
270 + 'carriersOptions' =>
271 + [
272 + 'packetery_carrier_zpoint-cz' =>
273 + [
274 + 'id' => 'zpoint-cz',
275 + 'name' => 'zpoint-cz',
276 + 'active' => true,
277 + 'free_shipping_limit' => null,
278 + 'weight_limits' =>
279 + [
280 + [
281 + 'weight' => 20.0,
282 + 'price' => 100.0,
283 + ],
284 + ],
285 + ],
286 + ],
287 + 'productDisallowedRateIds' => [],
288 + 'productCategoryDisallowedRateIds' => [],
289 + 'allowedCarrierNames' =>
290 + [
291 + 'zpoint-cz' => 'zpoint-cz',
292 + ],
293 + 'isCarDeliveryEnabled' => true,
294 + 'isAgeVerificationRequiredByProduct' => false,
295 + 'cartWeightKg' => 21.0,
296 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
297 + ],
298 + 'inactive carrier must be omitted' =>
299 + [
300 + 'expectedRateCount' => 0,
301 + 'carriers' =>
302 + [
303 + DummyFactory::createCarrierCzechPp(),
304 + ],
305 + 'carriersOptions' =>
306 + [
307 + 'packetery_carrier_zpoint-cz' =>
308 + [
309 + 'id' => 'zpoint-cz',
310 + 'name' => 'zpoint-cz',
311 + 'active' => false,
312 + 'free_shipping_limit' => null,
313 + 'weight_limits' =>
314 + [
315 + [
316 + 'weight' => 20.0,
317 + 'price' => 100.0,
318 + ],
319 + ],
320 + ],
321 + ],
322 + 'productDisallowedRateIds' => [],
323 + 'productCategoryDisallowedRateIds' => [],
324 + 'allowedCarrierNames' => [],
325 + 'isCarDeliveryEnabled' => true,
326 + 'isAgeVerificationRequiredByProduct' => false,
327 + 'cartWeightKg' => 1.0,
328 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
329 + ],
330 + 'carrier disallowed by product must be omitted' =>
331 + [
332 + 'expectedRateCount' => 0,
333 + 'carriers' =>
334 + [
335 + DummyFactory::createCarrierCzechPp(),
336 + ],
337 + 'carriersOptions' =>
338 + [
339 + 'packetery_carrier_zpoint-cz' =>
340 + [
341 + 'id' => 'zpoint-cz',
342 + 'name' => 'zpoint-cz',
343 + 'active' => true,
344 + ],
345 + ],
346 + 'productDisallowedRateIds' =>
347 + [
348 + 0 => 'packetery_carrier_zpoint-cz',
349 + ],
350 + 'productCategoryDisallowedRateIds' => [],
351 + 'allowedCarrierNames' =>
352 + [
353 + 'zpoint-cz' => 'zpoint-cz',
354 + ],
355 + 'isCarDeliveryEnabled' => true,
356 + 'isAgeVerificationRequiredByProduct' => false,
357 + 'cartWeightKg' => 1.0,
358 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
359 + ],
360 + 'carrier disallowed by product category must be omitted' =>
361 + [
362 + 'expectedRateCount' => 0,
363 + 'carriers' =>
364 + [
365 + DummyFactory::createCarrierCzechPp(),
366 + ],
367 + 'carriersOptions' =>
368 + [
369 + 'packetery_carrier_zpoint-cz' =>
370 + [
371 + 'id' => 'zpoint-cz',
372 + 'name' => 'zpoint-cz',
373 + 'active' => true,
374 + ],
375 + ],
376 + 'productDisallowedRateIds' => [],
377 + 'productCategoryDisallowedRateIds' =>
378 + [
379 + 0 => 'packetery_carrier_zpoint-cz',
380 + ],
381 + 'allowedCarrierNames' =>
382 + [
383 + 'zpoint-cz' => 'zpoint-cz',
384 + ],
385 + 'isCarDeliveryEnabled' => true,
386 + 'isAgeVerificationRequiredByProduct' => false,
387 + 'cartWeightKg' => 1.0,
388 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
389 + ],
390 + 'car delivery carriers must be supported' =>
391 + [
392 + 'expectedRateCount' => 1,
393 + 'carriers' =>
394 + [
395 + DummyFactory::createCarDeliveryCarrier(),
396 + ],
397 + 'carriersOptions' =>
398 + [
399 + 'packetery_carrier_25061' =>
400 + [
401 + 'id' => '25061',
402 + 'name' => 'CZ Zásilkovna do auta',
403 + 'active' => true,
404 + 'free_shipping_limit' => null,
405 + 'weight_limits' =>
406 + [
407 + [
408 + 'weight' => 20.0,
409 + 'price' => 234.34,
410 + ],
411 + ],
412 + ],
413 + ],
414 + 'productDisallowedRateIds' => [],
415 + 'productCategoryDisallowedRateIds' => [],
416 + 'allowedCarrierNames' =>
417 + [
418 + 25061 => 'CZ Zásilkovna do auta',
419 + ],
420 + 'isCarDeliveryEnabled' => true,
421 + 'isAgeVerificationRequiredByProduct' => false,
422 + 'cartWeightKg' => 1.0,
423 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
424 + ],
425 + 'carrier not supporting age verification must be omitted' =>
426 + [
427 + 'expectedRateCount' => 0,
428 + 'carriers' =>
429 + [
430 + DummyFactory::createCarDeliveryCarrier(),
431 + ],
432 + 'carriersOptions' =>
433 + [
434 + 'packetery_carrier_25061' =>
435 + [
436 + 'id' => '25061',
437 + 'name' => 'CZ Zásilkovna do auta',
438 + 'active' => true,
439 + 'free_shipping_limit' => null,
440 + 'weight_limits' =>
441 + [
442 + [
443 + 'weight' => 20.0,
444 + 'price' => 234.34,
445 + ],
446 + ],
447 + ],
448 + ],
449 + 'productDisallowedRateIds' => [],
450 + 'productCategoryDisallowedRateIds' => [],
451 + 'allowedCarrierNames' =>
452 + [
453 + 25061 => 'CZ Zásilkovna do auta',
454 + ],
455 + 'isCarDeliveryEnabled' => true,
456 + 'isAgeVerificationRequiredByProduct' => true,
457 + 'cartWeightKg' => 1.0,
458 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
459 + ],
460 + 'allowed carrier names argument must support null' =>
461 + [
462 + 'expectedRateCount' => 1,
463 + 'carriers' =>
464 + [
465 + DummyFactory::createCarDeliveryCarrier(),
466 + ],
467 + 'carriersOptions' =>
468 + [
469 + 'packetery_carrier_25061' =>
470 + [
471 + 'id' => '25061',
472 + 'name' => 'CZ Zásilkovna do auta',
473 + 'active' => true,
474 + 'free_shipping_limit' => null,
475 + 'weight_limits' =>
476 + [
477 + [
478 + 'weight' => 20.0,
479 + 'price' => 234.34,
480 + ],
481 + ],
482 + ],
483 + ],
484 + 'productDisallowedRateIds' => [],
485 + 'productCategoryDisallowedRateIds' => [],
486 + 'allowedCarrierNames' => null,
487 + 'isCarDeliveryEnabled' => true,
488 + 'isAgeVerificationRequiredByProduct' => false,
489 + 'cartWeightKg' => 1.0,
490 + 'shippingMethod' => ShippingMethod::PACKETERY_METHOD_ID,
491 + ],
292 492 ];
293 493 }
294 494
295 495 /**
296 - * @dataProvider createShippingRatesProvider
496 + * @dataProvider rateCreationDataProvider
497 + * @throws \PHPUnit\Framework\MockObject\Exception
297 498 */
298 499 public function testCreateShippingRates(
500 + int $expectedRateCount,
501 + array $carriers,
502 + array $carriersOptions,
503 + array $productDisallowedRateIds,
504 + array $productCategoryDisallowedRateIds,
299 505 ?array $allowedCarrierNames,
300 - string $methodId,
301 - int $instanceId,
302 - ?string $customerCountry,
303 - array $availableCarriers,
304 - float $cartTotal,
305 - float $cartWeight,
306 - float $totalValue,
307 - bool $isAgeVerificationRequired,
308 - array $disallowedRateIds,
309 - bool $oversized,
310 - bool $restrictedByCategory,
311 - bool $arePricesTaxInclusive,
312 - float $rateCost,
313 - int $expectedRateCount,
506 + bool $isCarDeliveryEnabled,
507 + bool $isAgeVerificationRequiredByProduct,
508 + float $cartWeightKg,
509 + string $shippingMethod,
314 510 ): void {
315 - $shippingRateFactory = $this->createShippingRateFactory();
511 + $this->createShippingRateFactoryMock();
316 512
317 - $this->checkoutServiceMock->method( 'getCustomerCountry' )->willReturn( $customerCountry );
513 + $this->wpAdapter
514 + ->expects( self::atLeast( $expectedRateCount ) )
515 + ->method( 'applyFilters' );
516 + $this->wpAdapter
517 + ->method( 'didAction' )
518 + ->willReturn( 1 );
318 519
319 - $carrierEntities = [];
320 - $optionsMap = [];
321 - foreach ( $availableCarriers as $pair ) {
322 - if ( is_array( $pair ) && count( $pair ) === 2 ) {
323 - /** @var array<Entity\Carrier, Carrier\Options> $pair */
324 - [ $carrier, $options ] = $pair;
520 + $cart = $this->createMock( WC_Cart::class );
521 + $cart
522 + ->method( 'get_coupons' )
523 + ->willReturn( [] );
524 + $this->wcAdapter
525 + ->method( 'cart' )
526 + ->willReturn( $cart );
325 527
326 - $carrierEntities[] = $carrier;
327 - $optionsMap[ $options->getOptionId() ] = $options;
328 - }
329 - }
528 + $wcProduct = $this->createMock( WC_Product::class );
529 + $wcProduct
530 + ->method( 'get_price' )
531 + ->willReturn( '100.00' );
532 + $wcProduct
533 + ->method( 'get_category_ids' )
534 + ->willReturn( [ 1 ] );
535 + $this->wcAdapter
536 + ->method( 'productFactoryGetProduct' )
537 + ->willReturn( $wcProduct );
330 538
331 - if ( $methodId === ShippingMethod::PACKETERY_METHOD_ID ) {
332 - $this->carrierEntityRepositoryMock
333 - ->method( 'getByCountryIncludingNonFeed' )
334 - ->willReturn( $carrierEntities );
335 - } else {
336 - $targetCarrier = $carrierEntities[0] ?? null;
337 - $this->carrierEntityRepositoryMock
338 - ->method( 'getAnyById' )
339 - ->willReturn( $targetCarrier );
340 - }
539 + $cartItem = [
540 + 'product_id' => 1,
541 + 'quantity' => 1.0,
542 + 'data' => $wcProduct,
543 + ];
544 + $this->wcAdapter
545 + ->method( 'cartGetCartContents' )
546 + ->willReturn( [ $cartItem ] );
547 + $this->wcAdapter
548 + ->method( 'cartGetCartContent' )
549 + ->willReturn( [ $cartItem ] );
341 550
342 - $this->carrierOptionsFactoryMock
551 + $this->checkoutService
552 + ->method( 'getCustomerCountry' )
553 + ->willReturn( 'cz' );
554 + $this->wcAdapter
555 + ->method( 'cartGetCartContentsTotal' )
556 + ->willReturn( 100.0 );
557 + $this->wcAdapter
558 + ->method( 'cartGetCartContentsTax' )
559 + ->willReturn( 21.0 );
560 + $this->cartService
561 + ->method( 'getCartWeightKg' )
562 + ->willReturn( $cartWeightKg );
563 +
564 + $productEntity = $this->createMock( Product\Entity::class );
565 + $productEntity
566 + ->method( 'isPhysical' )
567 + ->willReturn( true );
568 + $productEntity
569 + ->method( 'isAgeVerificationRequired' )
570 + ->willReturn( $isAgeVerificationRequiredByProduct );
571 + $productEntity
572 + ->method( 'getDisallowedShippingRateIds' )
573 + ->willReturn( array_merge( [ Carrier\OptionPrefixer::getOptionId( 'anyDisallowedOnProduct' ) ], $productDisallowedRateIds ) );
574 + $this->productEntityFactory
575 + ->method( 'fromPostId' )
576 + ->willReturn( $productEntity );
577 + $this->cartService
578 + ->method( 'isAgeVerificationRequired' )
579 + ->willReturn( $isAgeVerificationRequiredByProduct );
580 +
581 + $productCategory = $this->createMock( ProductCategory\Entity::class );
582 + $productCategory
583 + ->method( 'getDisallowedShippingRateIds' )
584 + ->willReturn( array_merge( [ Carrier\OptionPrefixer::getOptionId( 'anyDisallowedByProductCategory' ) ], $productCategoryDisallowedRateIds ) );
585 + $this->productCategoryEntityFactory = $this->createMock( ProductCategoryEntityFactory::class );
586 + $this->productCategoryEntityFactory
587 + ->method( 'fromTermId' )
588 + ->willReturn( $productCategory );
589 +
590 + $this->carrierOptionsFactory
343 591 ->method( 'createByOptionId' )
344 592 ->willReturnCallback(
345 - function ( string $optionId ) use ( $optionsMap ) {
346 - return $optionsMap[ $optionId ] ?? new Carrier\Options( $optionId, [ 'active' => true ] );
593 + function ( $optionId ) use ( $carriersOptions ) {
594 + $carrierOptions = $carriersOptions[ $optionId ];
595 +
596 + return new Carrier\Options(
597 + $optionId,
598 + $carrierOptions
599 + );
347 600 }
348 601 );
349 602
350 - $this->cartServiceMock->method( 'getCartContentsTotalIncludingTax' )->willReturn( $cartTotal );
351 - $this->cartServiceMock->method( 'getCartWeightKg' )->willReturn( $cartWeight );
352 - $this->cartServiceMock->method( 'getTotalCartProductValue' )->willReturn( $totalValue );
353 - $this->cartServiceMock->method( 'isAgeVerificationRequired' )->willReturn( $isAgeVerificationRequired );
354 - $this->cartServiceMock->method( 'getDisallowedShippingRateIds' )->willReturn( $disallowedRateIds );
355 - $this->cartServiceMock->method( 'cartContainsProductOversizedForCarrier' )->willReturn( $oversized );
356 - $this->cartServiceMock->method( 'isShippingRateRestrictedByProductsCategory' )->willReturn( $restrictedByCategory );
603 + $this->carrierEntityRepository
604 + ->method( 'getByCountryIncludingNonFeed' )
605 + ->willReturn( $carriers );
606 + $this->carrierEntityRepository
607 + ->method( 'getAnyById' )
608 + ->willReturn( $carriers[0] );
357 609
358 - $this->optionsProviderMock->method( 'arePricesTaxInclusive' )->willReturn( $arePricesTaxInclusive );
610 + $this->carDeliveryConfig
611 + ->method( 'isDisabled' )
612 + ->willReturn( ! $isCarDeliveryEnabled );
359 613
360 - $shippingRates = $shippingRateFactory->createShippingRates( $allowedCarrierNames, $methodId, $instanceId );
614 + $this->carrierActivityBridge
615 + ->method( 'isActive' )
616 + ->willReturnOnConsecutiveCalls( ...array_column( $carriersOptions, 'active' ) );
361 617
362 - self::assertCount( $expectedRateCount, $shippingRates );
363 - if ( $expectedRateCount > 0 ) {
364 - $firstRate = array_key_first( $shippingRates );
365 - if ( $methodId === ShippingMethod::PACKETERY_METHOD_ID ) {
366 - self::assertStringStartsWith( ShippingMethod::PACKETERY_METHOD_ID . ':', $firstRate );
367 - } else {
368 - self::assertStringStartsWith( $methodId . ':', $firstRate );
369 - }
370 - }
618 + $dummyInstanceId = 11;
619 + $rates = $this->shippingRateFactory->createShippingRates(
620 + $allowedCarrierNames,
621 + $shippingMethod,
622 + $dummyInstanceId,
623 + );
624 +
625 + self::assertCount( $expectedRateCount, $rates );
371 626 }
372 627 }