Skip to content
Merged
49 changes: 47 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ jobs:
with:
dependency-versions: "${{ matrix.dependencies }}"

- name: "Run phpunit"
run: "composer phpunit"
- name: "Run unit tests"
run: "vendor/bin/phpunit --testsuite unit"

integration-tests:
name: "Integration tests (PHP${{ matrix.php-version }} | Deps: ${{ matrix.dependencies }} | SF${{ matrix.symfony }})"
Expand Down Expand Up @@ -236,6 +236,14 @@ jobs:
with:
dependency-versions: "${{ matrix.dependencies }}"

- name: "Setup Node"
uses: "actions/setup-node@v7"
with:
node-version-file: "tests/Application/.nvmrc"

- name: "Build frontend assets"
run: "(cd tests/Application && yarn install && yarn build)"

- name: "Lint container"
run: "(cd tests/Application && bin/console lint:container)"

Expand All @@ -247,6 +255,9 @@ jobs:

- name: "Validate Doctrine mapping"
run: "(cd tests/Application && bin/console doctrine:schema:validate -vvv)" # The verbose flag will show 'missing' SQL statements, if any

- name: "Run functional tests"
run: "vendor/bin/phpunit --testsuite functional"

mutation-tests:
name: "Mutation tests"
Expand Down Expand Up @@ -277,6 +288,23 @@ jobs:
with:
dependency-versions: "${{ matrix.dependencies }}"

- name: "Setup Node"
uses: "actions/setup-node@v7"
with:
node-version-file: "tests/Application/.nvmrc"

- name: "Build frontend assets"
run: "(cd tests/Application && yarn install && yarn build)"

- name: "Start MySQL"
run: "sudo /etc/init.d/mysql start"

- name: "Create database"
run: "(cd tests/Application && bin/console doctrine:database:create)"

- name: "Create database schema"
run: "(cd tests/Application && bin/console doctrine:schema:create)"

- name: "Run infection"
run: "vendor/bin/infection"
env:
Expand Down Expand Up @@ -311,6 +339,23 @@ jobs:
with:
dependency-versions: "${{ matrix.dependencies }}"

- name: "Setup Node"
uses: "actions/setup-node@v7"
with:
node-version-file: "tests/Application/.nvmrc"

- name: "Build frontend assets"
run: "(cd tests/Application && yarn install && yarn build)"

- name: "Start MySQL"
run: "sudo /etc/init.d/mysql start"

- name: "Create database"
run: "(cd tests/Application && bin/console doctrine:database:create)"

- name: "Create database schema"
run: "(cd tests/Application && bin/console doctrine:schema:create)"

- name: "Collect code coverage with pcov and phpunit/phpunit"
run: "vendor/bin/phpunit --coverage-clover=.build/logs/clover.xml"

Expand Down
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,19 @@
"api-platform/core": "^2.7.16",
"babdev/pagerfanta-bundle": "^3.8",
"behat/behat": "^3.14",
"dama/doctrine-test-bundle": "^7.3",
"doctrine/doctrine-bundle": "^2.11",
"jms/serializer-bundle": "^4.2",
"lexik/jwt-authentication-bundle": "^2.17",
"nyholm/psr7": "^1.8",
"payum/payum-bundle": "^2.6 !=2.7.0",
"setono/sylius-plugin-pack": "~1.14.1",
"setono/tag-bag": "^2.3",
"setono/tag-bag-bundle": "^3.0",
"shipmonk/composer-dependency-analyser": "^1.6",
"sylius-labs/polyfill-symfony-security": "^1.1.2",
"symfony/browser-kit": "^6.4",
"symfony/css-selector": "^6.4",
"symfony/debug-bundle": "^6.4",
"symfony/dotenv": "^6.4",
"symfony/http-client": "^6.4",
Expand Down
4 changes: 2 additions & 2 deletions infection.json.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
"badge": "3.x"
}
},
"minMsi": 100.00,
"minCoveredMsi": 100.00
"minMsi": 87,
"minCoveredMsi": 87
}
13 changes: 11 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,19 @@
</include>
</coverage>
<testsuites>
<testsuite name="SetonoSyliusFacebookPlugin Test Suite">
<directory>tests</directory>
<!-- Unit tests do not need a database (run with the testsuite option set to "unit") -->
<testsuite name="unit">
<directory>tests/Unit</directory>
</testsuite>
<!-- Functional tests boot the test application and need the test database schema (testsuite option "functional") -->
<testsuite name="functional">
<directory>tests/Functional</directory>
</testsuite>
</testsuites>
<extensions>
<!-- Wraps every test in a database transaction that is rolled back afterwards -->
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
</extensions>
<php>
<env name="APP_ENV" value="test"/>
<env name="SHELL_VERBOSITY" value="-1"/>
Expand Down
2 changes: 1 addition & 1 deletion src/Event/FormatAmountTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

trait FormatAmountTrait
{
protected static function formatAmount(int $amount): float

Check warning on line 9 in src/Event/FormatAmountTrait.php

View workflow job for this annotation

GitHub Actions / Mutation tests (8.3, highest)

Escaped Mutant for Mutator "ProtectedVisibility": @@ @@ trait FormatAmountTrait { - protected static function formatAmount(int $amount): float + private static function formatAmount(int $amount): float { return $amount / 100; } }
{
return round($amount / 100, 2);
return $amount / 100;
Comment thread
loevgaard marked this conversation as resolved.
}
}
16 changes: 2 additions & 14 deletions src/Event/ProductAddedToCartEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Taxonomy\Model\TaxonInterface;
use Webmozart\Assert\Assert;

final class ProductAddedToCartEvent extends Event
Expand Down Expand Up @@ -78,19 +77,8 @@ private function populateProductInformation(ProductInterface $product): void

private function getTaxonName(ProductInterface $product): ?string
{
$taxon = $product->getMainTaxon();
if (null !== $taxon) {
return $taxon->getName();
}

$taxons = $product->getTaxons();
if ($taxons->isEmpty()) {
return null;
}

$taxon = $taxons->first();
Assert::isInstanceOf($taxon, TaxonInterface::class);
$taxon = $product->getMainTaxon() ?? $product->getTaxons()->first();

return $taxon->getName();
return false === $taxon ? null : $taxon->getName();
}
}
17 changes: 2 additions & 15 deletions src/Event/ProductViewedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

use Setono\MetaConversionsApi\Event\Event;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Taxonomy\Model\TaxonInterface;
use Webmozart\Assert\Assert;

final class ProductViewedEvent extends Event
{
Expand All @@ -23,19 +21,8 @@ public function __construct(ProductInterface $product)

private function getTaxonName(ProductInterface $product): ?string
{
$taxon = $product->getMainTaxon();
if (null !== $taxon) {
return $taxon->getName();
}
$taxon = $product->getMainTaxon() ?? $product->getTaxons()->first();

$taxons = $product->getTaxons();
if ($taxons->isEmpty()) {
return null;
}

$taxon = $taxons->first();
Assert::isInstanceOf($taxon, TaxonInterface::class);

return $taxon->getName();
return false === $taxon ? null : $taxon->getName();
}
}
13 changes: 3 additions & 10 deletions src/EventSubscriber/ViewCategorySubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Setono\SyliusFacebookPlugin\EventSubscriber;

use IteratorIterator;
use LimitIterator;
use Psr\EventDispatcher\EventDispatcherInterface;
use Setono\SyliusFacebookPlugin\Event\CategoryViewedEvent;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
Expand Down Expand Up @@ -69,23 +71,14 @@ private function getProducts(ResourceGridView $gridView): array

$codes = [];

$i = 0;
$max = 10;

/** @var mixed $datum */
foreach ($data as $datum) {
if ($i >= $max) {
break;
}

foreach (new LimitIterator(new IteratorIterator($data), 0, 10) as $datum) {
if ($datum instanceof ProductInterface) {
$code = $datum->getCode();
if (null !== $code) {
$codes[] = $code;
}
}

++$i;
}

return $codes;
Expand Down
2 changes: 1 addition & 1 deletion tests/Application/config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Symfony\Component\Dotenv\Dotenv;

require dirname(__DIR__) . '../../../vendor/autoload.php';
require_once dirname(__DIR__, 3) . '/vendor/autoload.php';

// Load cached env vars if the .env.local.php file exists
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
Expand Down
1 change: 1 addition & 0 deletions tests/Application/config/bundles.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true],
Sylius\Behat\Application\SyliusTestPlugin\SyliusTestPlugin::class => ['test' => true, 'test_cached' => true],
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true, 'test_cached' => true],
ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true],
Expand Down
140 changes: 140 additions & 0 deletions tests/Functional/Admin/ManagingPixelsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusFacebookPlugin\Tests\Functional\Admin;

use Setono\SyliusFacebookPlugin\Model\PixelInterface;
use Setono\SyliusFacebookPlugin\Tests\Functional\FunctionalTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\Security\Core\User\UserInterface;

final class ManagingPixelsTest extends FunctionalTestCase
{
/**
* @test
*/
public function it_lists_pixels(): void
{
$client = $this->createAuthenticatedClient();
self::createPixel('123456789', true, self::createChannel('WEB'));

$client->request('GET', '/admin/facebook/pixels/');

self::assertResponseIsSuccessful();
self::assertSelectorTextContains('table', '123456789');
}

/**
* @test
*/
public function it_creates_a_pixel(): void
{
$client = $this->createAuthenticatedClient();
self::createChannel('WEB');

$client->request('GET', '/admin/facebook/pixels/new');
self::assertResponseIsSuccessful();

$client->submitForm('Create', [
'setono_sylius_facebook_pixel[pixelId]' => '123456789',
'setono_sylius_facebook_pixel[accessToken]' => 'access_token',
'setono_sylius_facebook_pixel[enabled]' => '1',
'setono_sylius_facebook_pixel[channels]' => ['WEB'],
]);

self::assertResponseRedirects();
$client->followRedirect();
self::assertResponseIsSuccessful();

$pixel = self::getPixelRepository()->findOneBy(['pixelId' => '123456789']);
self::assertInstanceOf(PixelInterface::class, $pixel);
self::assertSame('access_token', $pixel->getAccessToken());
self::assertTrue($pixel->isEnabled());
self::assertCount(1, $pixel->getChannels());
}

/**
* @test
*/
public function it_does_not_create_a_pixel_with_an_invalid_pixel_id(): void
{
$client = $this->createAuthenticatedClient();
self::createChannel('WEB');

$client->request('GET', '/admin/facebook/pixels/new');
$client->submitForm('Create', [
'setono_sylius_facebook_pixel[pixelId]' => 'not a number',
'setono_sylius_facebook_pixel[channels]' => ['WEB'],
]);

self::assertSelectorExists('.sylius-validation-error');
self::assertNull(self::getPixelRepository()->findOneBy(['pixelId' => 'not a number']));
}

/**
* @test
*/
public function it_updates_a_pixel(): void
{
$client = $this->createAuthenticatedClient();
$pixelId = (int) self::createPixel('123456789', true, self::createChannel('WEB'))->getId();

$client->request('GET', sprintf('/admin/facebook/pixels/%d/edit', $pixelId));
self::assertResponseIsSuccessful();

$client->submitForm('Save changes', [
'setono_sylius_facebook_pixel[pixelId]' => '987654321',
'setono_sylius_facebook_pixel[enabled]' => false,
]);

self::assertResponseRedirects();

// The kernel is rebooted between requests, so fetch the pixel again instead of refreshing a detached entity
self::getEntityManager()->clear();
$pixel = self::getPixelRepository()->find($pixelId);
self::assertInstanceOf(PixelInterface::class, $pixel);
self::assertSame('987654321', $pixel->getPixelId());
self::assertFalse($pixel->isEnabled());
}

/**
* @test
*/
public function it_deletes_a_pixel(): void
{
$client = $this->createAuthenticatedClient();
$pixel = self::createPixel('123456789', true, self::createChannel('WEB'));
$pixelId = (int) $pixel->getId();

$client->request('GET', '/admin/facebook/pixels/');
$client->submitForm('Delete');

self::assertResponseRedirects();
self::getEntityManager()->clear();
self::assertNull(self::getPixelRepository()->find($pixelId));
}

/**
* @test
*/
public function it_requires_an_authenticated_administrator(): void
{
$client = self::createClient();

$client->request('GET', '/admin/facebook/pixels/');

self::assertResponseRedirects('/admin/login');
}

private function createAuthenticatedClient(): KernelBrowser
{
$client = self::createClient();

$adminUser = self::createAdminUser();
self::assertInstanceOf(UserInterface::class, $adminUser);
$client->loginUser($adminUser, 'admin');

return $client;
}
}
Loading
Loading