diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0f16752c6b0..525946873fa 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -60,6 +60,13 @@ jobs: - name: composer install run: composer install --dev --no-interaction -o --apcu-autoloader + - name: Setup pcov + run: | + sudo apt-fast install -y php7.4-pcov + sudo phpenmod -s cli pcov + composer require pcov/clobber --dev + vendor/bin/pcov clobber + - name: Setup EC-CUBE env: DATABASE_URL: ${{ matrix.database_url }} @@ -76,9 +83,7 @@ jobs: DATABASE_SERVER_VERSION: ${{ matrix.database_server_version }} MAILER_URL: 'smtp://127.0.0.1:1025' continue-on-error: true - run: | - bin/phpunit --version - phpdbg -dmemory_limit=-1 -qrr bin/phpunit --exclude-group cache-clear,cache-clear-install,update-schema-doctrine --coverage-clover=coverage1.xml + run: bin/phpunit --exclude-group cache-clear,cache-clear-install,update-schema-doctrine --coverage-clover=coverage1.xml - name: Upload report if: success() uses: actions/upload-artifact@v2 @@ -204,6 +209,7 @@ jobs: GROUP: ${{ matrix.group }} SYMFONY_DEPRECATIONS_HELPER: weak XDEBUG_MODE: coverage + continue-on-error: true run: vendor/bin/codecept -vvv run acceptance --env chrome,github_action -g ${GROUP} --skip-group excludeCoverage --coverage --coverage-xml - name: Upload outputs uses: actions/upload-artifact@v2 diff --git a/Dockerfile b/Dockerfile index 31de8669f53..1318e4fa5cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,9 @@ FROM php:7.4-apache-bullseye ENV APACHE_DOCUMENT_ROOT /var/www/html -RUN apt-get update \ - && apt-get install --no-install-recommends -y \ +RUN apt update \ + && apt upgrade -y \ + && apt install --no-install-recommends -y \ apt-transport-https \ apt-utils \ build-essential \ @@ -24,8 +25,8 @@ RUN apt-get update \ unzip \ zlib1g-dev \ libwebp-dev \ - && apt-get upgrade -y ca-certificates \ - && apt-get clean \ + && apt upgrade -y ca-certificates \ + && apt clean \ && rm -rf /var/lib/apt/lists/* \ && echo "en_US.UTF-8 UTF-8" >/etc/locale.gen \ && locale-gen \ @@ -39,8 +40,9 @@ RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ RUN pecl install apcu && echo "extension=apcu.so" > /usr/local/etc/php/conf.d/apc.ini RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \ - && apt-get install -y nodejs \ - && apt-get clean \ + && apt update \ + && apt install -y nodejs \ + && apt clean \ ; RUN mkdir -p ${APACHE_DOCUMENT_ROOT} \ diff --git a/codeception/acceptance/EA04OrderCest.php b/codeception/acceptance/EA04OrderCest.php index 5927d253194..36d6078ee88 100644 --- a/codeception/acceptance/EA04OrderCest.php +++ b/codeception/acceptance/EA04OrderCest.php @@ -48,7 +48,8 @@ public function order_受注検索(AcceptanceTester $I) OrderManagePage::go($I)->検索(); $I->see('検索結果:'.count($TargetOrders).'件が該当しました', OrderManagePage::$検索結果_メッセージ); - OrderManagePage::go($I)->検索($TargetOrders[0]->getName01()); + $TargetOrder = array_values($TargetOrders)[0]; + OrderManagePage::go($I)->検索($TargetOrder->getName01()); $I->dontSee('検索結果:0件が該当しました', OrderManagePage::$検索結果_メッセージ); OrderManagePage::go($I)->検索('gege@gege.com'); diff --git a/src/Eccube/Command/InstallerCommand.php b/src/Eccube/Command/InstallerCommand.php index 120fabbcee6..0b69464105a 100644 --- a/src/Eccube/Command/InstallerCommand.php +++ b/src/Eccube/Command/InstallerCommand.php @@ -130,6 +130,7 @@ protected function interact(InputInterface $input, OutputInterface $output) $databaseUrl = 'sqlite:///var/eccube.db'; } $this->envFileUpdater->databaseUrl = $this->io->ask('Database Url', $databaseUrl); + $databaseUrl = $this->envFileUpdater->databaseUrl; // DATABASE_SERVER_VERSION $this->envFileUpdater->serverVersion = $this->getDatabaseServerVersion($databaseUrl); @@ -252,7 +253,7 @@ protected function getDatabaseName($databaseUrl) if (0 === strpos($databaseUrl, 'sqlite')) { return 'sqlite'; } - if (0 === strpos($databaseUrl, 'postgres')) { + if (0 === strpos($databaseUrl, 'postgres') || 0 === strpos($databaseUrl, 'pgsql')) { return 'postgres'; } if (0 === strpos($databaseUrl, 'mysql')) { diff --git a/src/Eccube/Command/PluginGenerateCommand.php b/src/Eccube/Command/PluginGenerateCommand.php index df236b097c5..8bf720cec55 100644 --- a/src/Eccube/Command/PluginGenerateCommand.php +++ b/src/Eccube/Command/PluginGenerateCommand.php @@ -177,14 +177,15 @@ protected function createDirectories($pluginDir) */ protected function createConfig($pluginDir, $name, $code, $version) { + $lowerCode = mb_strtolower($code); $source = <<categoryRepository = $categoryRepository; $this->pageRepository = $pageRepository; $this->productListOrderByRepository = $productListOrderByRepository; $this->productRepository = $productRepository; $this->router = $router; + $this->BaseInfo = $baseInfoRepository->get(); } /** @@ -136,6 +145,10 @@ public function category() */ public function product(Request $request, PaginatorInterface $paginator) { + // Doctrine SQLFilter + if ($this->BaseInfo->isOptionNostockHidden()) { + $this->entityManager->getFilters()->enable('option_nostock_hidden'); + } // フロントの商品一覧の条件で商品情報を取得 $ProductListOrder = $this->productListOrderByRepository->find($this->eccubeConfig['eccube_product_order_newer']); $productQueryBuilder = $this->productRepository->getQueryBuilderBySearchData(['orderby' => $ProductListOrder]); diff --git a/src/Eccube/Entity/Cart.php b/src/Eccube/Entity/Cart.php index 049be480fbc..2b84b3919f8 100644 --- a/src/Eccube/Entity/Cart.php +++ b/src/Eccube/Entity/Cart.php @@ -349,9 +349,9 @@ public function getDeliveryFeeTotal() } /** - * @return Customer + * @return Customer|null */ - public function getCustomer(): Customer + public function getCustomer(): ?Customer { return $this->Customer; } diff --git a/src/Eccube/Entity/CartItem.php b/src/Eccube/Entity/CartItem.php index 316aa6fce4a..549c60ef386 100644 --- a/src/Eccube/Entity/CartItem.php +++ b/src/Eccube/Entity/CartItem.php @@ -259,6 +259,8 @@ public function getCart() public function setCart(Cart $Cart) { $this->Cart = $Cart; + + return $this; } } } diff --git a/src/Eccube/Form/Type/Admin/ShopMasterType.php b/src/Eccube/Form/Type/Admin/ShopMasterType.php index 8a4adf6de6b..21156d01296 100644 --- a/src/Eccube/Form/Type/Admin/ShopMasterType.php +++ b/src/Eccube/Form/Type/Admin/ShopMasterType.php @@ -134,7 +134,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'required' => false, 'constraints' => [ new Assert\Length([ - 'max' => $this->eccubeConfig['eccube_lltext_len'], + 'max' => $this->eccubeConfig['eccube_ltext_len'], ]), ], ]) @@ -142,7 +142,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'required' => false, 'constraints' => [ new Assert\Length([ - 'max' => $this->eccubeConfig['eccube_lltext_len'], + 'max' => $this->eccubeConfig['eccube_ltext_len'], ]), ], ]) diff --git a/src/Eccube/Resource/locale/messages.en.yaml b/src/Eccube/Resource/locale/messages.en.yaml index a14ee76b186..f4eeeaac4d6 100644 --- a/src/Eccube/Resource/locale/messages.en.yaml +++ b/src/Eccube/Resource/locale/messages.en.yaml @@ -369,6 +369,7 @@ front.shopping.out_of_stock_zero: 'Sorry, we do not have enough stock for %produ front.shopping.over_price_limit: Sorry, the quantity exceeds the max. purchase amount. Please reduce the purchase quantity. front.shopping.in_preparation: 'Sorry, %product% is not ready for shipment. Please contact us from the inquiry form. We are sorry for the inconvenience.' front.shopping.not_purchase: Sorry, your order includes item(s) currently unavailable. It has been deleted from your cart. +front.shopping.not_purchase_product_class: 'Sorry, %product% is currently unavailable. It has been deleted from your cart.' front.shopping.price_changed: 'The selling price of %product% has been changed.' front.shopping.payment_total_invalid: The total amount is invalid. front.shopping.different_payment_methods: Sorry, your order includes items with different purchase methods, which are unable to be processed in one order. diff --git a/src/Eccube/Resource/locale/messages.ja.yaml b/src/Eccube/Resource/locale/messages.ja.yaml index 8c2ff3a70e0..eef76b554ad 100644 --- a/src/Eccube/Resource/locale/messages.ja.yaml +++ b/src/Eccube/Resource/locale/messages.ja.yaml @@ -369,6 +369,7 @@ front.shopping.out_of_stock_zero: '「%product%」の在庫が不足しており front.shopping.over_price_limit: 商品を購入できる金額の上限を超えております。数量を調整してください。 front.shopping.in_preparation: '「%product%」はまだ配送の準備ができておりません。恐れ入りますがお問い合わせページよりお問い合わせください。' front.shopping.not_purchase: 現時点で購入できない商品が含まれておりました。該当商品をカートから削除しました。 +front.shopping.not_purchase_product_class: '「%product%」は現時点で購入できません。該当商品をカートから削除しました。' front.shopping.price_changed: '「%product%」の販売価格が変更されました。' front.shopping.payment_total_invalid: 合計金額が不正です。 front.shopping.different_payment_methods: 支払い方法が異なる商品が含まれているため、同時に購入することはできません。 diff --git a/src/Eccube/Service/PurchaseFlow/Processor/ProductStatusValidator.php b/src/Eccube/Service/PurchaseFlow/Processor/ProductStatusValidator.php index dc435579140..89ca7614343 100644 --- a/src/Eccube/Service/PurchaseFlow/Processor/ProductStatusValidator.php +++ b/src/Eccube/Service/PurchaseFlow/Processor/ProductStatusValidator.php @@ -33,7 +33,12 @@ class ProductStatusValidator extends ItemValidator protected function validate(ItemInterface $item, PurchaseContext $context) { if ($item->isProduct()) { - $Product = $item->getProductClass()->getProduct(); + $ProductClass = $item->getProductClass(); + if (!$item->getProductClass()->isVisible()) { + $this->throwInvalidItemException('front.shopping.not_purchase_product_class', $ProductClass); + } + + $Product = $ProductClass->getProduct(); if ($Product->getStatus()->getId() != ProductStatus::DISPLAY_SHOW) { $this->throwInvalidItemException('front.shopping.not_purchase'); } diff --git a/tests/Eccube/Tests/Form/Type/Admin/ShopMasterTypeTest.php b/tests/Eccube/Tests/Form/Type/Admin/ShopMasterTypeTest.php index 0f741c1ed3c..12bd75c7181 100644 --- a/tests/Eccube/Tests/Form/Type/Admin/ShopMasterTypeTest.php +++ b/tests/Eccube/Tests/Form/Type/Admin/ShopMasterTypeTest.php @@ -156,4 +156,16 @@ public function testInValidBasicPointRateRangeMax() $this->form->submit($this->formData); $this->assertFalse($this->form->isValid()); } + public function testInValidGoodTradedMaxLength() + { + $this->formData['good_traded'] = str_repeat('1', $this->eccubeConfig['eccube_ltext_len'] + 1); + $this->form->submit($this->formData); + $this->assertFalse($this->form->isValid()); + } + public function testInValidMessageMaxLength() + { + $this->formData['message'] = str_repeat('1', $this->eccubeConfig['eccube_ltext_len'] + 1); + $this->form->submit($this->formData); + $this->assertFalse($this->form->isValid()); + } } diff --git a/tests/Eccube/Tests/Repository/AbstractProductRepositoryTestCase.php b/tests/Eccube/Tests/Repository/AbstractProductRepositoryTestCase.php index 74db312be47..632033363ee 100644 --- a/tests/Eccube/Tests/Repository/AbstractProductRepositoryTestCase.php +++ b/tests/Eccube/Tests/Repository/AbstractProductRepositoryTestCase.php @@ -85,6 +85,12 @@ protected function createFavorites($Customer) */ protected function setProductTags(Product $Product, array $tagIds) { + $ProductTags = $Product->getProductTag(); + foreach ($ProductTags as $ProductTag) { + $Product->removeProductTag($ProductTag); + $this->entityManager->remove($ProductTag); + } + $Tags = $this->tagRepository->findBy(['id' => $tagIds]); foreach ($Tags as $Tag) { $ProductTag = new ProductTag(); diff --git a/tests/Eccube/Tests/Repository/ProductRepositoryGetQueryBuilderBySearchDataAdminTest.php b/tests/Eccube/Tests/Repository/ProductRepositoryGetQueryBuilderBySearchDataAdminTest.php index f9bede17e0b..c9c563cbc34 100644 --- a/tests/Eccube/Tests/Repository/ProductRepositoryGetQueryBuilderBySearchDataAdminTest.php +++ b/tests/Eccube/Tests/Repository/ProductRepositoryGetQueryBuilderBySearchDataAdminTest.php @@ -376,6 +376,7 @@ public function testTagSearch() $Products[0]->setName('りんご'); $this->setProductTags($Products[0], [1]); $this->setProductTags($Products[1], [1, 2]); + $this->setProductTags($Products[2], []); $this->entityManager->flush(); // タグ 1 で検索 diff --git a/tests/Eccube/Tests/Service/CartServiceTest.php b/tests/Eccube/Tests/Service/CartServiceTest.php index b93de033281..c69e0fd6edf 100644 --- a/tests/Eccube/Tests/Service/CartServiceTest.php +++ b/tests/Eccube/Tests/Service/CartServiceTest.php @@ -100,7 +100,7 @@ public function setUp() public function testClear() { - $this->cartService->addProduct(1); + $this->cartService->addProduct(2); $this->purchaseFlow->validate($this->cartService->getCart(), new PurchaseContext()); $this->cartService->save(); @@ -172,7 +172,7 @@ public function testAddProductsWithCartItemComparator() // 同じ商品規格で同じ数量なら同じ明細とみなすようにする $this->cartService->setCartItemComparator(new CartServiceTest_CartItemComparator()); - $ProductClass = $this->productClassRepository->find(1); + $ProductClass = $this->productClassRepository->find(2); $this->cartService->addProduct($ProductClass, 1); $this->purchaseFlow->validate($this->cartService->getCart(), new PurchaseContext()); @@ -185,7 +185,7 @@ public function testAddProductsWithCartItemComparator() /* @var \Eccube\Entity\CartItem[] $CartItems */ $CartItems = $this->cartService->getCart()->getCartItems(); self::assertEquals(1, count($CartItems)); - self::assertEquals(1, $CartItems[0]->getProductClassId()); + self::assertEquals(2, $CartItems[0]->getProductClassId()); self::assertEquals(2, $CartItems[0]->getQuantity()); $this->cartService->addProduct($ProductClass, 1); @@ -195,9 +195,9 @@ public function testAddProductsWithCartItemComparator() /* @var \Eccube\Entity\CartItem[] $CartItems */ $CartItems = $this->cartService->getCart()->getCartItems(); self::assertEquals(2, count($CartItems)); - self::assertEquals(1, $CartItems[0]->getProductClassId()); + self::assertEquals(2, $CartItems[0]->getProductClassId()); self::assertEquals(2, $CartItems[0]->getQuantity()); - self::assertEquals(1, $CartItems[1]->getProductClassId()); + self::assertEquals(2, $CartItems[1]->getProductClassId()); self::assertEquals(1, $CartItems[1]->getQuantity()); } diff --git a/tests/Eccube/Tests/Service/PurchaseFlow/Processor/ProductStatusValidatorTest.php b/tests/Eccube/Tests/Service/PurchaseFlow/Processor/ProductStatusValidatorTest.php index 6075ae018c5..f7bff2ea91c 100644 --- a/tests/Eccube/Tests/Service/PurchaseFlow/Processor/ProductStatusValidatorTest.php +++ b/tests/Eccube/Tests/Service/PurchaseFlow/Processor/ProductStatusValidatorTest.php @@ -85,4 +85,17 @@ public function testDisplayStatusWithClosed() self::assertEquals(0, $this->cartItem->getQuantity()); } + + + /** + * 無効になっている商品規格の場合は明細の個数を0に設定する. + */ + public function testProductClassVisibleFalse() + { + $this->ProductClass->setVisible(false); + + $this->validator->execute($this->cartItem, new PurchaseContext()); + + self::assertEquals(0, $this->cartItem->getQuantity()); + } } diff --git a/tests/Eccube/Tests/Web/AbstractShoppingControllerTestCase.php b/tests/Eccube/Tests/Web/AbstractShoppingControllerTestCase.php index a1bf9c3e2ae..aa0e56e74a4 100644 --- a/tests/Eccube/Tests/Web/AbstractShoppingControllerTestCase.php +++ b/tests/Eccube/Tests/Web/AbstractShoppingControllerTestCase.php @@ -63,7 +63,7 @@ public function createShippingFormData() return $form; } - protected function scenarioCartIn(Customer $Customer = null, $product_class_id = 1) + protected function scenarioCartIn(Customer $Customer = null, $product_class_id = 2) { if ($Customer) { $this->loginTo($Customer); diff --git a/tests/Eccube/Tests/Web/ShoppingControllerTest.php b/tests/Eccube/Tests/Web/ShoppingControllerTest.php index dc2d4877374..e38925ebe0f 100644 --- a/tests/Eccube/Tests/Web/ShoppingControllerTest.php +++ b/tests/Eccube/Tests/Web/ShoppingControllerTest.php @@ -648,7 +648,7 @@ public function testPaymentLimitAndPointCombination() $price = 27777; $pointUse = 27777; /** @var ProductClass $ProductClass */ - $ProductClass = $this->entityManager->getRepository(\Eccube\Entity\ProductClass::class)->find(1); + $ProductClass = $this->entityManager->getRepository(\Eccube\Entity\ProductClass::class)->find(2); $ProductClass->setPrice02($price); $this->entityManager->flush($ProductClass); @@ -660,7 +660,7 @@ public function testPaymentLimitAndPointCombination() $COD2 = self::$container->get(Generator::class)->createPayment($Delivery, 'COD2', 0, 30001, 300000); // カート画面 - $this->scenarioCartIn($Customer, 1); + $this->scenarioCartIn($Customer, 2); // 確認画面 $this->scenarioConfirm($Customer); diff --git a/tests/Eccube/Tests/Web/ShoppingControllerWithMultipleNonmemberTest.php b/tests/Eccube/Tests/Web/ShoppingControllerWithMultipleNonmemberTest.php index 47142b42eaa..88f4c63edfe 100644 --- a/tests/Eccube/Tests/Web/ShoppingControllerWithMultipleNonmemberTest.php +++ b/tests/Eccube/Tests/Web/ShoppingControllerWithMultipleNonmemberTest.php @@ -198,8 +198,8 @@ public function testAddMultiShippingWithOneAddressOneItem() */ public function testAddMultiShippingWithOneAddressOneItemTwoQuantities() { - $this->scenarioCartIn(null, 1); - $this->scenarioCartIn(null, 1); + $this->scenarioCartIn(null, 2); + $this->scenarioCartIn(null, 2); $formData = $this->createNonmemberFormData(); $this->scenarioInput($formData);