Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# NEXT

- [BREAKING] [#178](https://github.com/shopware/SwagMigrationAssistant/pull/190) - fix!: update product.sales during migration
- [BREAKING] [#202](https://github.com/shopware/SwagMigrationAssistant/pull/202) - fix!: replace native time reads with an injected clock
- [BREAKING] Added required constructor parameter `Psr\Clock\ClockInterface $clock` to `\SwagMigrationAssistant\Profile\Shopware\Converter\ShippingMethodConverter`
- [BREAKING] [#190](https://github.com/shopware/SwagMigrationAssistant/pull/190) - fix!: update product.sales during migration
- [BREAKING] Added required constructor parameter `\SwagMigrationAssistant\Migration\Service\ProductSalesUpdater` to `\SwagMigrationAssistant\Migration\Writer\OrderWriter`

# 18.0.0
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ parameters:
path: src/DataProvider/Provider/Data/AbstractProvider.php

# TODO: remove this for 6.8 compatibility
- message: '#Call to deprecated method scope\(\) of class Shopware\\Core\\Framework\\Context#'
- message: '#Call to deprecated method addFlags\(\) of class Shopware\\Core\\Framework\\DataAbstractionLayer\\Field\\Field#'
- message: '#Call to deprecated method setFlags\(\) of class Shopware\\Core\\Framework\\DataAbstractionLayer\\Field\\Field#'
- message: '#Access to constant on deprecated class Shopware\\Core\\Checkout\\Payment\\Cart\\PaymentHandler\\DebitPayment#'
Expand Down
4 changes: 3 additions & 1 deletion src/Controller/DataProviderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use League\Flysystem\FilesystemOperator;
use League\Flysystem\UnableToGenerateTemporaryUrl;
use Psr\Clock\ClockInterface;
use Psr\Http\Message\StreamInterface;
use Shopware\Core\Checkout\Document\Service\DocumentGenerator;
use Shopware\Core\Content\Media\MediaCollection;
Expand Down Expand Up @@ -52,6 +53,7 @@ public function __construct(
private readonly MediaService $mediaService,
private readonly FilesystemOperator $privateFilesystem,
private readonly MigrationApiRateLimiter $rateLimiter,
private readonly ClockInterface $clock,
) {
}

Expand Down Expand Up @@ -183,7 +185,7 @@ public function downloadPrivateFile(Request $request, Context $context): Streame
}

try {
$url = $this->privateFilesystem->temporaryUrl($media->getPath(), (new \DateTime())->modify('+120 minutes'));
$url = $this->privateFilesystem->temporaryUrl($media->getPath(), $this->clock->now()->add(new \DateInterval('PT120M')));

return new RedirectResponse($url);
} catch (UnableToGenerateTemporaryUrl) {
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/dataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Psr\Clock\ClockInterface;
use Shopware\Core\Checkout\Document\Service\DocumentGenerator;
use Shopware\Core\Content\Media\MediaService;
use Shopware\Core\Framework\Store\Services\AbstractExtensionDataProvider;
Expand Down Expand Up @@ -87,6 +88,7 @@
service(MediaService::class),
service('shopware.filesystem.private'),
service(MigrationApiRateLimiter::class),
service(ClockInterface::class),
])
->call('setContainer', [service('service_container')]);

Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/shopware.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Doctrine\DBAL\Connection;
use Psr\Clock\ClockInterface;
use Shopware\Core\Checkout\Cart\Tax\TaxCalculator;
use Shopware\Core\Checkout\Promotion\PromotionDefinition;
use Shopware\Core\Content\Media\File\FileSaver;
Expand Down Expand Up @@ -454,6 +455,7 @@
->args([
service(CountryLookup::class),
service(LanguageLookup::class),
service(ClockInterface::class),
]);

$services->set(ProductReviewConverter::class)
Expand Down
4 changes: 3 additions & 1 deletion src/Profile/Shopware/Converter/ShippingMethodConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace SwagMigrationAssistant\Profile\Shopware\Converter;

use Psr\Clock\ClockInterface;
use Shopware\Core\Checkout\Shipping\Aggregate\ShippingMethodPrice\ShippingMethodPriceDefinition;
use Shopware\Core\Checkout\Shipping\ShippingMethodDefinition;
use Shopware\Core\Framework\Context;
Expand Down Expand Up @@ -79,6 +80,7 @@ public function __construct(
LoggingServiceInterface $loggingService,
protected readonly CountryLookup $countryLookup,
protected readonly LanguageLookup $languageLookup,
private readonly ClockInterface $clock,
) {
parent::__construct($mappingService, $loggingService);
}
Expand Down Expand Up @@ -762,7 +764,7 @@ private function setCustomAvailabilityRule(array $data, array &$converted): void
],
],
'name' => $converted['name'],
'description' => 'Migrated at ' . (new \DateTime())->format('d.m.Y H:i'),
'description' => 'Migrated at ' . $this->clock->now()->format('d.m.Y H:i'),
];

$mainOrContainerMapping = $this->mappingService->getOrCreateMapping(
Expand Down
3 changes: 2 additions & 1 deletion src/SwagMigrationAssistant.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use SwagMigrationAssistant\Migration\Media\SwagMigrationMediaFileDefinition;
use SwagMigrationAssistant\Migration\Run\SwagMigrationRunDefinition;
use SwagMigrationAssistant\Migration\Setting\GeneralSettingDefinition;
use Symfony\Component\Clock\NativeClock;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
Expand Down Expand Up @@ -91,7 +92,7 @@ public function postInstall(InstallContext $installContext): void

/** @var Connection $connection */
$connection = $this->container->get(Connection::class);
$now = (new \DateTime())->format(Defaults::STORAGE_DATE_TIME_FORMAT);
$now = (new NativeClock())->now()->format(Defaults::STORAGE_DATE_TIME_FORMAT);

$connection->beginTransaction();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Clock\ClockInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
Expand Down Expand Up @@ -67,7 +68,8 @@ protected function setUp(): void
$this->mappingService,
$this->loggingService,
static::getContainer()->get(CountryLookup::class),
static::getContainer()->get(LanguageLookup::class)
static::getContainer()->get(LanguageLookup::class),
static::getContainer()->get(ClockInterface::class)
);

$runId = Uuid::randomHex();
Expand Down Expand Up @@ -142,7 +144,8 @@ public function testConvert(): void
$this->mappingService,
$this->loggingService,
static::getContainer()->get(CountryLookup::class),
$languageLookup
$languageLookup,
static::getContainer()->get(ClockInterface::class)
);

$convertResult = $shippingMethodConverter->convert($shippingMethodData[0], $this->context, $this->migrationContext);
Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/fixtures/TestHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const VIEWPORT = {

export const loaderSelectors = [
'.sw-loader-element',
'.mt-loader-element',
'.mt-loader__element',
'.mt-skeleton-bar',
'.sw-skeleton',
] as const;
Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default defineConfig({

expect: {
toHaveScreenshot: {
maxDiffPixelRatio: 0.01,
maxDiffPixels: 100,
threshold: 0.2,
animations: 'disabled',
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Comment thread
vintagesucks marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Comment thread
vintagesucks marked this conversation as resolved.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 10 additions & 10 deletions tests/acceptance/tests/BasicVisualTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ test.describe('Visual Regression Tests @visual', () => {
await page.getByRole('button', { name: 'Open Migration Assistant' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('main-page-general-no-connection.png', { mask });
await expect.soft(page).toHaveScreenshot('main-page-general-no-connection.png', { mask });

await page.getByTitle('Data selection').click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('main-page-data-selection-empty.png', { mask });
await expect.soft(page).toHaveScreenshot('main-page-data-selection-empty.png', { mask });
});

test('Main page (with connection)', async ({ ShopAdmin, MigrationConnection: _ }) => {
Expand All @@ -34,12 +34,12 @@ test.describe('Visual Regression Tests @visual', () => {
await page.getByRole('button', { name: 'Open Migration Assistant' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('main-page-general-with-connection.png', { mask });
await expect.soft(page).toHaveScreenshot('main-page-general-with-connection.png', { mask });

await page.getByTitle('Data selection').click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('main-page-data-selection.png', { mask });
await expect.soft(page).toHaveScreenshot('main-page-data-selection.png', { mask });
});

test('Connection wizard (local, happy path)', async ({ ShopAdmin, DatabaseCredentials }) => {
Expand All @@ -55,17 +55,17 @@ test.describe('Visual Regression Tests @visual', () => {
await page.getByRole('button', { name: 'Create initial connection' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('connection-wizard-introduction.png', { mask });
await expect.soft(page).toHaveScreenshot('connection-wizard-introduction.png', { mask });

await page.getByRole('button', { name: 'Start' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('connection-wizard-profiles.png', { mask });
await expect.soft(page).toHaveScreenshot('connection-wizard-profiles.png', { mask });

await page.getByRole('button', { name: 'Continue' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('connection-wizard-create.png', { mask });
await expect.soft(page).toHaveScreenshot('connection-wizard-create.png', { mask });

await page.getByPlaceholder('Enter name').fill('shopware55local');

Expand All @@ -78,7 +78,7 @@ test.describe('Visual Regression Tests @visual', () => {
// lose focus of host input
await page.getByText('Migration').click();

await expect(page).toHaveScreenshot('connection-wizard-establish-local.png', { mask });
await expect.soft(page).toHaveScreenshot('connection-wizard-establish-local.png', { mask });

await page.getByPlaceholder('Enter host').fill(DatabaseCredentials.host);
await page.getByLabel('Port').fill(DatabaseCredentials.port);
Expand All @@ -97,7 +97,7 @@ test.describe('Visual Regression Tests @visual', () => {
await page.getByRole('button', { name: 'Truncate migration' }).click();
await page.getByRole('button', { name: 'Archive' }).click();

await expect(page).toHaveScreenshot('connection-wizard-truncation.png', { mask });
await expect.soft(page).toHaveScreenshot('connection-wizard-truncation.png', { mask });

await waitForLoaders(page, 300_000); // wait for truncation

Expand All @@ -122,6 +122,6 @@ test.describe('Component Visual Tests @visual @components', () => {
const dashboardCard = page.locator('.swag-migration-dashboard-card');

await expect(dashboardCard).toBeVisible();
await expect(dashboardCard).toHaveScreenshot('dashboard-card.png');
await expect.soft(dashboardCard).toHaveScreenshot('dashboard-card.png');
});
});
30 changes: 17 additions & 13 deletions tests/acceptance/tests/MigrationTest.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable playwright/no-conditional-in-test */
/* eslint-disable playwright/no-conditional-expect */
import { test, expect } from '@fixtures/AcceptanceTest';
import { test, expect, replaceElements } from '@fixtures/AcceptanceTest';
import { getMask, waitForLoaders, withLargerViewport } from '@fixtures/TestHelpers';

test.describe('Migration Tests @migration @visual', () => {
Expand Down Expand Up @@ -53,7 +53,7 @@ test.describe('Migration Tests @migration @visual', () => {
await waitForLoaders(page);

const restoreViewport = await withLargerViewport(page);
await expect(page).toHaveScreenshot('data-selection-assigment-with-errors.png', { mask });
await expect.soft(page).toHaveScreenshot('data-selection-assigment-with-errors.png', { mask });
await restoreViewport();

const tabs = page.locator('.swag-migration-tab-card__title');
Expand All @@ -75,7 +75,7 @@ test.describe('Migration Tests @migration @visual', () => {
}
}

await expect(page).toHaveScreenshot('data-selection-assigment-without-errors.png', { mask });
await expect.soft(page).toHaveScreenshot('data-selection-assigment-without-errors.png', { mask });
});

await test.step('Start migration', async () => {
Expand All @@ -85,7 +85,7 @@ test.describe('Migration Tests @migration @visual', () => {
await page.getByRole('button', { name: 'Continue anyway' }).click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('migration-process-started.png', { mask });
await expect.soft(page).toHaveScreenshot('migration-process-started.png', { mask });

const step = page.locator('.sw-step-display > .sw-step-item').first();
await expect(step).toHaveClass(/sw-step-item--success/, { timeout: 300_000 });
Expand All @@ -96,7 +96,7 @@ test.describe('Migration Tests @migration @visual', () => {

await test.step('Error resolution', async () => {
let restoreViewport = await withLargerViewport(page);
await expect(page).toHaveScreenshot('error-resolution-log-groups-unfixed.png', { mask });
await expect.soft(page).toHaveScreenshot('error-resolution-log-groups-unfixed.png', { mask });
await restoreViewport();

await waitForLoaders(page);
Expand Down Expand Up @@ -171,14 +171,14 @@ test.describe('Migration Tests @migration @visual', () => {
await processLogEntry(i);

if (i === 0) {
await expect(page).toHaveScreenshot('error-resolution-log-detail-unfixed.png', { mask });
await expect.soft(page).toHaveScreenshot('error-resolution-log-detail-unfixed.png', { mask });
}

await page.getByRole('button', { name: 'Apply changes' }).click();
await waitForLoaders(page);

if (i === 0) {
await expect(page).toHaveScreenshot('error-resolution-log-detail-fixed.png', { mask });
await expect.soft(page).toHaveScreenshot('error-resolution-log-detail-fixed.png', { mask });
}

await page.locator('.sw-modal__close').click();
Expand All @@ -188,7 +188,7 @@ test.describe('Migration Tests @migration @visual', () => {
await waitForLoaders(page);

restoreViewport = await withLargerViewport(page);
await expect(page).toHaveScreenshot('error-resolution-log-groups-fixed.png', { mask });
await expect.soft(page).toHaveScreenshot('error-resolution-log-groups-fixed.png', { mask });
await restoreViewport();

await expect(page.locator('.swag-migration-error-resolution-step__card-table-count-icon')).toHaveCount(logCount);
Expand All @@ -210,7 +210,7 @@ test.describe('Migration Tests @migration @visual', () => {
await waitForLoaders(page);
await expect(page.getByText('The Migration is done')).toBeVisible({ timeout: 300_000 });

await expect(page).toHaveScreenshot('migration-process-summary.png', { mask });
await expect.soft(page).toHaveScreenshot('migration-process-summary.png', { mask });

await page.getByRole('button', { name: 'Back to overview' }).click();
await waitForLoaders(page);
Expand All @@ -220,17 +220,21 @@ test.describe('Migration Tests @migration @visual', () => {
await page.getByTitle('History').click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('migration-history-list.png', {
mask: getMask(page, ['.sw-data-grid__cell--createdAt']),
});
const createdAtCellContent = page.locator('.sw-data-grid__cell--createdAt .sw-data-grid__cell-content');

await replaceElements(page, [createdAtCellContent]);

await expect.soft(page).toHaveScreenshot('migration-history-list.png', { mask });

await page.locator('.sw-data-grid__body .sw-data-grid__cell--actions').getByRole('button').click();
await waitForLoaders(page);

await page.locator('.sw-context-menu__content .sw-context-menu-item').first().click();
await waitForLoaders(page);

await expect(page).toHaveScreenshot('migration-history-details-modal.png', { mask });
await replaceElements(page, [createdAtCellContent]);

await expect.soft(page).toHaveScreenshot('migration-history-details-modal.png', { mask });
});

await test.step('Verify migrated entities', async () => {
Expand Down
Loading