get(CartFactory::class); $sharedCartFromPurchaseUtil = $this->get(PurchaseUtil::class)->getCart(); $sharedCartFromDI = $this->get(\KupShop\OrderingBundle\Cart::class); $this->assertSame(spl_object_id($sharedCartFromDI), spl_object_id($sharedCartFromPurchaseUtil), 'Rikam si o shared Cart, takze musi byt vzdy stejny ID objektu v pameti'); $nonSharedCartFromFactory = $cartFactory->create(); $this->assertNotSame(spl_object_id($sharedCartFromDI), spl_object_id($nonSharedCartFromFactory), 'Shared a non-shared cart nesmi byt stejny'); $this->assertNotSame(spl_object_id($nonSharedCartFromFactory), spl_object_id($cartFactory->create()), 'Mam non-shared cart a vytvarim dalsi non-shared cart, ktery nesmi byt stejny jako ten predesly'); } public function testNonSharedCartDependencies(): void { $cart = $this->get(CartFactory::class)->create(); $requiredProperties = $this->getRequiredProperties($cart); $reflection = new ReflectionClass($cart); // test that all required properties are not null foreach ($reflection->getProperties() as $property) { if (!in_array($property->getName(), $requiredProperties)) { continue; } $property->setAccessible(true); $this->assertNotNull($property->getValue($cart), '#[Required] property nemuze byt null pokud se vytvari non-shared kosik pres CartFactory!'); } } // otestuje, ze se objednavka vytvori po novu pres PurchaseState /** @dataProvider data_purchaseStateProvider */ public function testOrderSubmitFromPurchaseState($applyModule): void { $applyModule(); $this->addModule(Modules::ORDERS, Modules::SUB_ORDERS_FROM_PURCHASE_STATE); $this->prepareCart(); $this->insertProduct(1, 16, 3); $this->insertProduct(10); $order = $this->submitOrder(); $this->removeModule(Modules::ORDERS, Modules::SUB_ORDERS_FROM_PURCHASE_STATE); $this->assertInstanceOf(Order::class, $order); $this->assertCount(2, $order->items); $this->assertEquals(4009, $order->getTotalPrice()->getPriceWithVat()->asFloat()); $this->assertEqualsWithDelta($this->cart->totalPricePay->asFloat(), $this->order->total_price->asFloat(), 0.01); $this->assertEquals(OrderInfo::ORDER_SOURCE_SHOP, $order->source); } /** @dataProvider data_DeliveryPriceNotOnFirstStep */ public function testCartDeliveryPriceNotOnFirstStep($goBack, $expectedPrice) { $this->createCart(); $this->insertProduct(1, 16, 1); $this->setDeliveryType(2); $this->visitStep('delivery'); if ($goBack) { $this->cart->actualStep = 'cart'; } $this->cart->createFromDB(); $this->assertEquals($expectedPrice, $this->cart->totalPricePay->asFloat()); } public function data_DeliveryPriceNotOnFirstStep() { yield [true, 800]; yield [false, 870]; } /** @dataProvider data_purchaseStateProvider */ public function testOrderingRegistrationInForeignCurrency($applyModule) { $applyModule(); $order = $this->getContextManager()->activateContexts( [ CurrencyContext::class => 'EUR', UserContext::class => ContextManager::FORCE_EMPTY, ], function () { $this->createCart(); $this->insertProduct(1, 16, 1); $this->setInvoice(); $this->setDeliveryType(); $this->cart->register = true; $this->cart->createFromDB(); return $this->cart->submitOrder(); } ); $this->assertEquals('EUR', $order->currency); } /** * @dataProvider data_orderingRegistration */ public function testOrderingRegistration($newsletterEnable, $getNewsExpect) { $settings = Settings::getDefault(); $settings->newsletter['enable'] = $newsletterEnable; $this->createCart(); $this->insertProduct(1, 16, 1); $this->setInvoice(); $this->setDeliveryType(); $this->cart->register = true; $this->cart->createFromDB(); $order = $this->cart->submitOrder(); // createFromLogin to avoid cached user when using getCurrentUser $user = User::createFromLogin('test@wpj.cz'); $this->assertInstanceOf(Order::class, $order); $this->assertEquals('800', $order->total_price->asFloat()); $this->assertEquals($user['email'], 'test@wpj.cz'); $this->assertEquals($user['get_news'], $getNewsExpect); } public function data_orderingRegistration() { return [ ['Y', 'N'], ['N', 'Y'], ]; } /** @dataProvider data_purchaseStateProvider */ public function testGetPayments($applyModule) { $applyModule(); $this->createCart(); $this->cart->createFromDB(); $payments = $this->cart->getPayments(); $this->assertEquals(12, $payments[1]['price']['value_with_vat']->asFloat()); $this->assertEquals(round(12 / 1.21, 4), $payments[1]['price']['value_without_vat']->asFloat()); $this->assertEquals(24, $payments[2]['price']['value_with_vat']->asFloat()); $this->assertEquals(36, $payments[3]['price']['value_with_vat']->asFloat()); $this->assertEquals(48, $payments[4]['price']['value_with_vat']->asFloat()); } /** @dataProvider data_purchaseStateProvider */ public function testAddItemToCart($applyModule) { $applyModule(); $this->loginUser(1); $this->createCart(); $this->insertProduct(1, 16); $this->cart->createFromDB(); $this->assertEquals(800, $this->cart->totalPriceWithVat->asFloat()); $this->checkOrderPriceIsSameAsCart(); } /** @dataProvider data_purchaseStateProvider */ public function testAddItemToCartNegativePieces($applyModule) { $applyModule(); $this->createCart(); $item = ['id_product' => 1, 'id_variation' => 16, 'pieces' => -1]; $itemId = $this->cart->addItem($item); $this->assertEmpty($itemId); $item = ['id_product' => 1, 'id_variation' => 16, 'pieces' => 0]; $itemId = $this->cart->addItem($item); $this->assertEmpty($itemId); $this->cart->createFromDB(); $this->assertEquals(0, $this->cart->totalPriceWithVat->asFloat()); $this->assertEmpty($this->cart->products); } /** @dataProvider data_purchaseStateProvider */ public function testCheckItemsInCartNotInStore($applyModule) { $applyModule(); // order_not_in_store == Y $this->createCart(); $this->insertProduct(1, 16, 2); $this->cart->createFromDB(); $return = $this->cart->checkCartItems(); $this->assertEquals(null, $return); } /** @dataProvider data_purchaseStateProvider */ public function testCheckItemsInCartInStore($applyModule) { $applyModule(); global $dbcfg, $cfg; $cfg['Modules']['products_suppliers'] = false; $dbcfg->order_not_in_store = 'N'; // order_not_in_store == N $this->createCart(); $this->insertProduct(1, 16, 2); $this->cart->createFromDB(); $this->expectException(\KupShop\OrderingBundle\Exception\CartValidationException::class); $return = $this->cart->checkCartItems(); $this->assertEquals(30, $return); } public function testCheckItemsInCartVisibility() { $this->createCart(); $this->insertProduct(4, 1, 1); $this->cart->createFromDB(); // cart product variation is visible $return = $this->cart->checkCartItems(); $this->assertEquals(null, $return); $qb = sqlQueryBuilder()->update('products_variations') ->directValues(['figure' => 'N']) ->andWhere('id=1')->execute(); // cart product variation is not visible $return = $this->cart->checkCartItems(); $this->assertEquals(31, $return); } /** @dataProvider data_purchaseStateProvider */ public function testCheckItemsInCartInSupplierStore($applyModule) { $applyModule(); global $dbcfg, $cfg; $cfg['Modules']['products_suppliers'] = ['delivery_time' => -2]; $dbcfg->order_not_in_store = 'N'; // order_not_in_store == N $this->createCart(); $this->insertProduct(1, 16, 2); $this->cart->createFromDB(); $return = $this->cart->checkCartItems(); $this->assertEquals(null, $return); } public function getDataSet() { return $this->getJsonDataSet( /* @lang JSON */ ' {"products_of_suppliers" : [ { "id":1, "id_product":1, "id_variation":16, "id_supplier":1, "code":123, "in_store":2 } ]}' ); } /** @dataProvider data_purchaseStateProvider */ public function testAddItemToCartInEuro($applyModule) { $applyModule(); $this->loginUser(1); $c = $this->get(\KupShop\KupShopBundle\Context\CurrencyContext::class); $c->activate('EUR'); $currency = $this->get(\KupShop\KupShopBundle\Context\CurrencyContext::class)->getActive(); $currency->setRate(toDecimal(26)); $currency->setPriceRoundOrder('0'); $currency->setPriceRound('0'); $this->createCart(); $this->insertProduct(1, 16); $this->cart->createFromDB(); $this->assertEquals(800 / 26, $this->cart->totalPricePay->asFloat(), '', 0.01); $this->checkOrderPriceIsSameAsCart(); changeCurrency(); } /** @dataProvider data_purchaseStateProvider */ public function testAddItemToCartInEuroWithRounding($applyModule) { $applyModule(); $this->loginUser(1); $context = $this->get(\KupShop\KupShopBundle\Context\CurrencyContext::class); $context->activate('EUR'); $currency = $context->getActive(); $currency->setRate(26); $currency->setPriceRoundOrder('100'); $this->createCart(); $this->insertProduct(1, 16); $this->cart->createFromDB(); $this->assertEquals(round(800 / 26), $this->cart->totalPricePay->asFloat(), '', 0.01); $this->checkOrderPriceIsSameAsCart(); } public function testSendZboziConversion() { // Prepare settings Settings::getDefault()->analytics = [ 'zbozi_cz_feedback' => [ 'ID' => '129931', 'secret_key' => 'CXIGnEMhnOrP32au62B7k5tgAOhiTiyK', ], ]; // Restart container to force reload event listeners $this->tearDownContainer(); $this->restoreDefaultCtrl(); $zboziClientMock = $this->getMockBuilder(\Soukicz\Zbozicz\Client::class) ->setMethods(['sendOrder']) ->setConstructorArgs(['129931', 'CXIGnEMhnOrP32au62B7k5tgAOhiTiyK']) ->getMock(); $data = []; $zboziClientMock->expects($this->once())->method('sendOrder')->with( $this->callback(function (Soukicz\Zbozicz\Order $order) use (&$data, $zboziClientMock) { $data = json_decode_strict($zboziClientMock->createRequest($order)->getBody(), true); return true; }) ); $requestStack = $this->getRequestStackWithCookies('cookie-bar', 'analytics_storage'); $listenerMock = $this->getMockBuilder(OrderConversionListener::class) ->setMethods(['getZboziClient']) ->setConstructorArgs( [ $this->get(\KupShop\KupShopBundle\Util\Price\PriceUtil::class), $requestStack, $this->get(\KupShop\KupShopBundle\Context\CountryContext::class), $this->get(\KupShop\KupShopBundle\Context\CurrencyContext::class), ] ) ->getMock(); $listenerMock->method('getZboziClient')->willReturn($zboziClientMock); $listenerMock->setDomainContext(\KupShop\KupShopBundle\Util\Contexts::get(\KupShop\KupShopBundle\Context\DomainContext::class)); $this->set(OrderConversionListener::class, $listenerMock); $this->loginUser(2); $context = $this->get(\KupShop\KupShopBundle\Context\CurrencyContext::class); $context->activate('EUR'); $this->createCart(); $this->insertProduct(1, 16); $this->cart->createFromDB(); $order = $this->cart->submitOrder(); $this->assertInstanceOf('\Order', $order); $this->assertNotEmpty($data); $this->assertEquals([ 'PRIVATE_KEY' => 'CXIGnEMhnOrP32au62B7k5tgAOhiTiyK', 'orderId' => $order->order_no, 'email' => 'wpj@wpj.cz', 'deliveryType' => 'GLS', 'deliveryPrice' => 104, 'paymentType' => 'dobírka PPL', 'cart' => [ [ 'productName' => 'DeWALT DeWALT DCD780C2 aku vrtačka', 'itemId' => '9', 'unitPrice' => 6000, 'quantity' => '1', ], [ 'productName' => 'Nike NIKE Capri LACE Test Dlouheho Nazvu Produktu Test Dlouheho Produktu Tes (Velikost: 45)', 'itemId' => '1_16', 'unitPrice' => 800, 'quantity' => '1', ], ], 'sandbox' => false, 'otherCosts' => 0, ], $data); } /** @dataProvider data_purchaseStateProvider */ public function testHeurekaConversionOptions($applyModule) { $applyModule(); /** @var OrderConversionListener $listener */ $listener = $this->get(OrderConversionListener::class); /** @var \KupShop\KupShopBundle\Context\CountryContext $countryContext */ $countryContext = $this->get(\KupShop\KupShopBundle\Context\CountryContext::class); $languageContext = $this->get(\KupShop\KupShopBundle\Context\LanguageContext::class); // Prepare settings Settings::getDefault()->analytics = [ 'heureka_overeno' => [ 'ID' => 'dksag41s2fdsd10vs', ], ]; $this->assertEquals( ['heureka_id' => 'dksag41s2fdsd10vs', 'options' => ['service' => ShopCertification::HEUREKA_CZ]], $listener->getHeurekaOptions() ); $languageContext->activate('sk'); Settings::getDefault()->analytics = [ 'heureka_overeno' => [ 'ID' => 'dksag41s2fdsd10vs', ], ]; $this->assertEquals( ['heureka_id' => 'dksag41s2fdsd10vs', 'options' => ['service' => ShopCertification::HEUREKA_SK]], $listener->getHeurekaOptions() ); $cfg = Config::get(); $languageContext->activate('cs'); $cfg['Modules']['translations'] = false; \Settings::clearCache(true); Settings::getDefault()->analytics = [ 'heureka_overeno' => [ 'ID' => 'dksag41s2fdsd10vs', ], ]; $this->assertEquals( ['heureka_id' => 'dksag41s2fdsd10vs', 'options' => ['service' => ShopCertification::HEUREKA_CZ]], $listener->getHeurekaOptions() ); Settings::getDefault()->analytics = [ 'heureka_overeno' => [ 'ID' => 'dksag41s2fdsd10vs', 'ID_SK' => 'SKdksag41s2fdsd10vsSK', ], ]; $languageContext->activate('sk'); $countryContext->activate('SK'); Settings::getDefault()->analytics = [ 'heureka_overeno' => [ 'ID' => 'dksag41s2fdsd10vs', 'ID_SK' => 'SKdksag41s2fdsd10vsSK', ], ]; $this->assertEquals( ['heureka_id' => 'SKdksag41s2fdsd10vsSK', 'options' => ['service' => ShopCertification::HEUREKA_SK]], $listener->getHeurekaOptions() ); } /** @dataProvider data_purchaseStateProvider */ public function testFreeDelivery($applyModule) { $applyModule(); sqlQuery('UPDATE delivery_type SET price_dont_countin_from=800 WHERE id=4'); $this->createCart(); $this->setInvoice(); $this->insertProduct(1, 16); $this->setDeliveryType(4); $this->checkOrderPriceIsSameAsCart(); $this->assertEquals('800', $this->cart->totalPricePay->asFloat()); } /** @dataProvider data_purchaseStateProvider */ public function testFreeDeliveryForUnregisteredWithUser($applyModule) { $applyModule(); // pro neregistrované je nastaveno 800, ale melo by platit i pro registrovane. sqlQuery('UPDATE delivery_type SET price_dont_countin_from=800 WHERE id=4'); $user = User::createFromId(1); $user->activateUser(); $this->createCart(); $this->insertProduct(1, 16); $this->setDeliveryType(4); $this->checkOrderPriceIsSameAsCart(); $this->assertEquals('800', $this->cart->totalPricePay->asFloat()); } public function testFreeDeliveryForRegisteredWithoutUser() { // Pro neregistrované není nic nastaveno, pro registrované od 400, tzn tento neni registrovany a ma se mu pricist doprava sqlQuery('UPDATE delivery_type SET price_dont_countin_from_reg=400 WHERE id=4'); $this->createCart(); $this->setInvoice(); $this->insertProduct(1, 16); $this->setDeliveryType(4); $this->visitStep('delivery'); $this->checkOrderPriceIsSameAsCart(); $this->assertEquals('904', $this->cart->totalPricePay->asFloat()); } /** @dataProvider data_purchaseStateProvider */ public function testFreeDeliveryForRegisteredWithtUser($applyModule) { $applyModule(); // Pro neregistrované není nic nastaveno, pro registrované od 400, tzn tento neni registrovany a nema se mu pricist doprava sqlQuery('UPDATE delivery_type SET price_dont_countin_from_reg=400 WHERE id=4'); $user = User::createFromId(1); $user->activateUser(); $this->createCart(); $this->insertProduct(1, 16); $this->setDeliveryType(4); $this->visitStep('delivery'); $this->checkOrderPriceIsSameAsCart(); $this->assertEquals('800', $this->cart->totalPricePay->asFloat()); } /** @dataProvider data_purchaseStateProvider */ public function testCartClean($applyModule) { $applyModule(); // vytvoříme nový košík, který by neměl být smazán - ostatní jsou staršího data, tak dojde k jejich smazání $this->createCart(); $this->insertProduct(1, 16); $cl = new \KupShop\OrderingBundle\EventListener\CronListener(); $cl->cartCleanup(); $this->assertTableRowCount('cart', 2); } /** @dataProvider data_purchaseStateProvider */ public function testDeliveryPrice(callable $applyModule): void { $applyModule(); $cart = $this->prepareCart(); $cart->setTransport(3); $product = [ 'id_product' => 7, 'id_variation' => 8, 'pieces' => 1, ]; $cart->addItem($product); $cart->createFromDB(); $order = $cart->submitOrder(); $price = $order->getTotalPrice(); $this->assertEqualsWithDelta(922.0, $price->getPriceWithVat()->asFloat(), 1); } }