Files
kupshop/tests/functional/ProductListTest.php
2025-08-02 16:30:27 +02:00

559 lines
19 KiB
PHP

<?php
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\UserContext;
require_once __DIR__.'/../../class/class.ProductList.php';
class ProductListTest extends DatabaseTestCase
{
/** @var ProductListBase */
private $productList;
public function setUp(): void
{
$this->productList = $this->createProductList();
parent::setUp();
}
/**
* Otestuje pocitani cen produktu ze shora.
*
* Pro zemi CZ je DPH 21%, takze tam by se to melo chovat standartne.
* Pro zemi SK je DPH 20%, takze se cena musi prepocitat, aby se zachovala stejna cena jako s defaultnim DPH.
*
* @dataProvider data_testProductListWithPricesWithVatFromTop
*/
public function testProductListWithPricesWithVatFromTop(string $country): void
{
// zapnu pocitani cen produktu ze shora
Settings::getDefault()->prod_vats_from_top = 'Y';
// zapnu OSS, abych mohl testovat zmeny DPH pri zmene zeme
Settings::getDefault()->oss_vats = [
'active' => 'Y',
];
$this->get(ContextManager::class)->activateContexts(
[CountryContext::class => $country],
function () {
$this->productList->fetchVariations([1 => true]);
$product = $this->getProduct();
$this->assertNotEmpty($product->variations);
$this->assertEquals(800, $product->getProductPrice()->getPriceWithVat()->asFloat(), 'Cena na produktu musi byt 800 Kc');
foreach ($product->variations as $variation) {
$this->assertEquals(800, $variation['productPrice']->getPriceWithVat()->asFloat(), 'Cena na variante musi byt 800 Kc');
}
}
);
}
public function data_testProductListWithPricesWithVatFromTop(): array
{
return [
['CZ'],
['SK'],
];
}
/**
* Otestuje pocitani cen produktu ze shora pro SK uzivatele s vyplnenym DIC => NO_VAT.
*/
public function testProductListWithPricesWithVatFromTopNoVat(): void
{
// zapnu pocitani cen produktu ze shora
Settings::getDefault()->prod_vats_from_top = 'Y';
// zapnu OSS, abych mohl testovat zmeny DPH pri zmene zeme
Settings::getDefault()->oss_vats = [
'active' => 'Y',
];
$this->get(ContextManager::class)->activateContexts([
CountryContext::class => 'SK',
UserContext::class => 10, // SK uzivatel s vyplnenym DIC => NO_VAT
],
function () {
$this->productList->fetchVariations([1 => true]);
$product = $this->getProduct();
// cena = 800 - 20% DPH = 666.668969293 = 667
$this->assertEquals(667, $product->getProductPrice()->getPriceWithVat()->asFloat(), 'Cena na produktu musi byt 667 Kc');
foreach ($product->variations as $variation) {
$this->assertEquals(667, $variation['productPrice']->getPriceWithVat()->asFloat(), 'Cena na variante musi byt 667 Kc');
}
$productList = $this->createProductList(productId: 10); // produkt s vat = 2 (Snížená 15% daň)
$product = $this->getProduct($productList);
// cena s DPH = 1748.7600 + 15% DPH - 20% sleva = 1608.8592
// cena SK = 1608.8592 - 20% = 1340.716
$this->assertEquals(1341, $product->getProductPrice()->getPriceWithVat()->asFloat(), 'Cena na produktu musi byt 1341 Kc');
}
);
}
/**
* Otestuje pocitani cen produktu ze shora pro SK uzivatele s vyplnenym DIC => NO_VAT.
* Se snizenou sazbou DPH.
*/
public function testProductListWithPricesWithVatFromTopNoVatLevelLow(): void
{
// zapnu pocitani cen produktu ze shora
Settings::getDefault()->prod_vats_from_top = 'Y';
// zapnu OSS, abych mohl testovat zmeny DPH pri zmene zeme
Settings::getDefault()->oss_vats = [
'active' => 'Y',
'homeCountry' => 'CZ',
'default' => '80200000080', // Snížená sazba DPH -> SK 10%
];
$this->get(ContextManager::class)->activateContexts([
CountryContext::class => 'SK',
UserContext::class => 10, // SK uzivatel s vyplnenym DIC => NO_VAT
],
function () {
$this->productList->fetchVariations([1 => true]);
$product = $this->getProduct();
// cena = 800 - 10% DPH = 727.272727273
$this->assertEquals(727, $product->getProductPrice()->getPriceWithVat()->asFloat(), 'Cena na produktu musi byt 727 Kc');
foreach ($product->variations as $variation) {
$this->assertEquals(727, $variation['productPrice']->getPriceWithVat()->asFloat(), 'Cena na variante musi byt 727 Kc');
}
$productList = $this->createProductList(productId: 10); // produkt s vat = 2 (Snížená 15% daň)
$product = $this->getProduct($productList);
// cena s DPH = 1748.7600 + 15% DPH - 20% sleva = 1608.8592
// cena SK = 1608.8592 - 10% = 1462.59927273
$this->assertEquals(1463, $product->getProductPrice()->getPriceWithVat()->asFloat(), 'Cena na produktu musi byt 1463 Kc');
}
);
}
public function testPlainProductHasNoAdditionalData()
{
$product = $this->getProduct();
$this->assertEmpty($product->image);
$this->assertEmpty($product->variations);
$this->assertEmpty($product->param);
$this->assertEmpty($product->collections);
$this->assertEmpty($product->field_producerTitle());
$this->assertEmpty($product['producerTitle']);
}
public function testFetchImages()
{
$productList = $this->createProductList(false, 2);
$productList->fetchImages(1);
$product = $this->getProduct($productList);
$this->assertNotEmpty($product->image);
}
public function testFetchImagesOfVariationsOnlyDoesntFetchImageWithNoVariation()
{
$productList = new ProductListBase(true);
$productList->fetchImages(1);
$productList->andSpec(function (Query\QueryBuilder $qb) {
return $qb->expr()->eq('p.id', 2);
});
/** @var Product $product */
$product = $productList->getProducts()->current();
$this->assertEmpty($product->image);
}
public function testFetchImagesOfVariationsOnlyDoesFetchImageWithVariation()
{
$productList = new ProductListBase(true);
$productList->fetchImages(1);
$productList->andSpec(function (Query\QueryBuilder $qb) {
return $qb->expr()->eq('p.id', 1);
});
/** @var Product $product */
$product = $productList->getProducts()->current();
$this->assertNotEmpty($product->image);
}
public function testFetchProducers()
{
$this->productList->fetchProducers();
$product = $this->getProduct();
$this->assertNotEmpty($product->field_producerTitle());
$this->assertNotEmpty($product->field_producerImage());
$this->assertNotEmpty($product['producerTitle']);
$this->assertNotEmpty($product['producerImage']);
}
public function testFetchSets()
{
$this->productList->fetchSets(true);
$product = $this->getProduct();
$this->assertNotEmpty($product->sets);
}
public function testFetchStoresInStore()
{
$this->productList->fetchStoresInStore();
$storesInStore = $this->getProduct()->storesInStore;
$this->assertEquals(1, $storesInStore[2]['in_store'], 'Na prodejne jsou skladem 3ks');
}
public function testFetchVariations()
{
$this->skipIfNoModule('products_variations');
$this->productList->fetchVariations([1 => true]);
$product = $this->getProduct();
$this->assertEquals([6, 8], array_keys($product->variations));
$this->assertArraySubset([
'id' => '6',
'id_product' => '7',
'code' => null,
'ean' => null,
'title' => 'Barva: modrá',
'in_store' => 0,
'delivery_time' => '-1',
'figure' => 'Y',
'updated' => '0000-00-00 00:00:00',
'date_added' => '0000-00-00 00:00:00',
'note' => null,
'weight' => null,
'price_buy' => null,
'bonus_points' => null,
'width' => null,
'height' => null,
'depth' => null,
'pohoda_sync_date' => null,
'data' => [
],
'price_common' => null,
'value_1' => 'Modrá',
'value_code_1' => null,
'photo' => null,
'values' => [
1 => 'Modrá',
],
'values_codes' => [
1 => null,
],
'delivery_time_text' => 'na cestě',
], $product->variations[6]);
$this->assertCount(2, $product->variations);
}
public function testFetchParameters()
{
$this->productList->fetchParameters();
$product = $this->getProduct();
$this->assertNotEmpty($product->param);
}
public function testFetchCollections()
{
$this->productList->fetchCollections();
$product = $this->getProduct();
$this->assertNotEmpty($product->collections);
$this->assertEquals([1 => 1, 7 => 7, 8 => 8, 9 => 9, 10 => 10], array_map(function ($product) {return $product->id; }, $product->collections));
}
public function testFetchCollectionsMultiple()
{
$productList = new ProductList();
$productList->fetchCollections();
$products = $productList->getProducts();
$collection_arr = [1 => 1, 7 => 7, 8 => 8, 9 => 9, 10 => 10];
foreach ($products as $product) {
if (!is_null($product->collections)) {
$arr = array_map(function ($product) {return $product->id; }, $product->collections);
$this->assertEquals($collection_arr, $arr);
}
}
}
public function testOrderBy()
{
$productListASC = new ProductListBase();
$productListDESC = new ProductListBase();
$ids = function () {
return function (Query\QueryBuilder $qb) {
return $qb->expr()->in('p.id', [7, 8]);
};
};
$productListASC->andSpec($ids);
$productListDESC->andSpec($ids);
$productListASC->orderBy('p.id', 'ASC');
$productListDESC->orderBy('p.id', 'DESC');
$this->assertNotSame(
$productListASC->getProducts()->getKeys(),
$productListDESC->getProducts()->getKeys()
);
}
public function testTotalCount()
{
$this->productList->getProducts($totalCount);
$this->assertSame(1, $totalCount);
}
/**
* @dataProvider dataProvider_testGetProductsCount
*
* @param bool $variationsAsResult
* @param int $expectedCount
*/
public function testGetProductsCount($variationsAsResult, $expectedCount, array $productKeys)
{
$this->assertSame($expectedCount, (new ProductListBase($variationsAsResult))->getProductsCount());
$this->assertSame($expectedCount, count($products = (new ProductListBase($variationsAsResult))->getProducts()));
$products = (new ProductListBase($variationsAsResult))->getProducts();
$this->assertEquals($productKeys, $products->getKeys(), '', 0.0, 10, true);
}
public function dataProvider_testGetProductsCount()
{
return [
'products' => [false, 11, range(1, 11)],
'variations as products' => [
true,
22,
[
'1/16',
'2/9',
'2/10',
'2/11',
'2/12',
3,
'4/1',
'4/2',
'5/13',
'5/14',
'5/15',
'6/17',
'6/18',
'6/19',
'7/6',
'7/8',
8,
9,
10,
'11/20',
'11/21',
'11/22',
],
],
];
}
public function testCreatesVariations()
{
$products = (new ProductListBase(true))->getProducts($totalCount);
foreach ($products as $index => $product) {
$expectedClassName = 'Product';
if (strpos($index, '/') !== false) {
$expectedClassName = 'Variation';
}
$this->assertInstanceOf($expectedClassName, $product);
}
$this->assertCount(22, $products);
}
public function createProductList($variationsAsResult = false, $productId = 7)
{
$productList = new ProductListBase($variationsAsResult);
$productList->andSpec(function () use ($productId) {
return function (Query\QueryBuilder $qb) use ($productId) {
return $qb->expr()->eq('p.id', $productId);
};
});
return $productList;
}
/**
* @return Product
*/
private function getProduct(?ProductListBase $productList = null)
{
if (!$productList) {
$productList = $this->productList;
}
$products = $productList->getProducts();
$this->assertCount(1, $products);
return $products->current();
}
public function getDataSet()
{
return new \PHPUnit\DbUnit\DataSet\ArrayDataSet([
'products_sets' => [
[
'id_product' => 7,
'id_product_set' => 1,
'price' => 100,
],
],
'products_collections' => [
[
'id_product' => 1,
'id_product_related' => 7,
],
[
'id_product' => 1,
'id_product_related' => 8,
],
[
'id_product' => 1,
'id_product_related' => 9,
],
[
'id_product' => 1,
'id_product_related' => 10,
],
],
'photos_products_relation' => [
[
'id_photo' => 1,
'id_product' => 1,
'id_variation' => 16,
'show_in_lead' => 'Y',
'active' => 'Y',
'date_added' => '2013-09-13 11:08:27',
'position' => 0,
],
[
'id_photo' => 2,
'id_product' => 1,
'id_variation' => 16,
'show_in_lead' => 'Y',
'active' => 'Y',
'date_added' => '2013-09-13 11:08:36',
'position' => 1,
],
[
'id_photo' => 3,
'id_product' => 2,
'id_variation' => null,
'show_in_lead' => 'Y',
'active' => 'Y',
'date_added' => '2013-09-13 11:22:49',
'position' => 0,
],
],
'stores' => [
[
'id' => 1,
'position' => 0,
'name' => 'Hlavní sklad',
'type' => 1,
'figure' => 'Y',
],
[
'id' => 2,
'position' => 1,
'name' => 'Prodejna',
'type' => 0,
'figure' => 'Y',
],
],
'stores_items' => [
[
'id' => 400,
'id_store' => 2,
'id_product' => 7,
'id_variation' => 8,
'quantity' => 1,
],
],
'users' => [
[
'id' => 10,
'id_language' => 'cs',
'passw' => '79c2b46ce2594ecbcb5b73e928345492',
'user_key' => '',
'figure' => 'Y',
'name' => 'Petr',
'surname' => 'Jebavý',
'firm' => 'wpj s.r.o.',
'street' => 'Nádražní 471',
'city' => 'Vrchlabí',
'zip' => '54301',
'country' => 'SK',
'currency' => 'CZK',
'email' => 'petr@wpj.cz',
'ico' => '50649361',
'dic' => 'SK2120408730',
'phone' => '775131400',
'mobile' => '',
'fax' => '',
'gender' => null,
'delivery_name' => '',
'delivery_surname' => '',
'delivery_firm' => '',
'delivery_street' => '',
'delivery_city' => '',
'delivery_zip' => '',
'delivery_country' => '',
'account_no' => '',
'account_bank' => '',
'account_symbol' => '',
'get_news' => 'Y',
'prefer_transport' => 1,
'date_reg' => '2013-09-30 12:09:05',
'date_updated' => '2013-09-30 12:12:44',
'date_logged' => null,
'custom_address' => '',
'state' => '',
'delivery_custom_address' => '',
'delivery_state' => '',
'date_subscribe' => '2013-09-30 12:09:05',
'date_unsubscribe' => null,
'note' => null,
'custom_data' => null,
'delivery_phone' => '',
'delivery_email' => null,
'pohoda_id' => null,
'pohoda_sync_date' => null,
'pohoda_id_address' => null,
'id_pricelist' => null,
'due_days' => null,
'birthdate' => null,
'copy_email' => null,
],
],
'vats_cns' => [
[
'id_cn' => 80200000080,
'id_vat' => 15,
'automanaged' => 1,
],
],
]);
}
}