-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
name: App Zip | ||
on: | ||
workflow_dispatch: | ||
pull_request: | ||
paths: | ||
- 'Resources/**/*' | ||
- 'templates/manifest.xml.twig' | ||
- '.shopware-extension.yml' | ||
- .github/workflows/app-zip.yml | ||
|
||
jobs: | ||
zip: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: ./.github/actions/setup-php | ||
- name: Generate manifest.xml | ||
run: composer setup:manifest -- -f --env=prod | ||
- uses: shopware/github-actions/build-zip@main | ||
with: | ||
extensionName: SwagBraintreeApp | ||
skipCheckout: 'true' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,3 +32,4 @@ public/build | |
###< vite ### | ||
|
||
Resources/app/storefront/dist | ||
manifest.xml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Swag\Braintree\Command; | ||
|
||
use Symfony\Component\Console\Attribute\AsCommand; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Console\Style\SymfonyStyle; | ||
use Symfony\Component\DependencyInjection\Attribute\Autowire; | ||
use Twig\Environment; | ||
|
||
#[AsCommand(name: 'manifest:generate')] | ||
class ManifestGenerateCommand extends Command | ||
{ | ||
public function __construct( | ||
#[Autowire(env: 'APP_URL')] | ||
private readonly ?string $appUrl, | ||
#[Autowire(env: 'APP_SECRET')] | ||
private readonly ?string $appSecret, | ||
#[Autowire(param: 'kernel.environment')] | ||
private readonly ?string $environment, | ||
#[Autowire(param: 'kernel.project_dir')] | ||
private readonly ?string $projectDir, | ||
#[Autowire(service: 'twig')] | ||
private readonly Environment $twig, | ||
) { | ||
parent::__construct(); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$io = new SymfonyStyle($input, $output); | ||
|
||
if ($this->appUrl === null || $this->appSecret === null || $this->environment === null || $this->projectDir === null) { | ||
Check warning on line 35 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
Check warning on line 35 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
Check warning on line 35 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
$io->error('Missing environment variables'); | ||
|
||
return Command::FAILURE; | ||
} | ||
|
||
$manifest = $this->twig->render('manifest.xml.twig', [ | ||
Check warning on line 41 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
'appUrl' => $this->environment === 'prod' ? 'https://braintree.shopware.com' : $this->appUrl, | ||
Check warning on line 42 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
Check warning on line 42 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
'appSecret' => $this->appSecret, | ||
Check warning on line 43 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
'isProd' => $this->environment === 'prod', | ||
Check warning on line 44 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
]); | ||
|
||
$write = true; | ||
|
||
if ($this->manifestExists() && !$input->getOption('force')) { | ||
$write = $io->confirm('manifest.xml already exists. Do you want to overwrite it?', false); | ||
} | ||
|
||
if ($write) { | ||
$success = $this->writeManifest($manifest); | ||
|
||
if ($success === false) { | ||
$io->error('Could not write manifest.xml'); | ||
|
||
return Command::FAILURE; | ||
} | ||
} | ||
|
||
return Command::SUCCESS; | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this->setDescription('Generate the manifest.xml'); | ||
Check warning on line 68 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
$this->addOption('force', 'f', null, 'Force overwrite'); | ||
Check warning on line 69 in src/Command/ManifestGenerateCommand.php GitHub Actions / infection
|
||
} | ||
|
||
protected function manifestExists(): bool | ||
{ | ||
return \file_exists($this->projectDir . '/manifest.xml'); | ||
} | ||
|
||
protected function writeManifest(string $manifest): bool | ||
{ | ||
return \file_put_contents($this->projectDir . '/manifest.xml', $manifest) !== false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Swag\Braintree\Tests\Unit\Command; | ||
|
||
use PHPUnit\Framework\Attributes\CoversClass; | ||
use PHPUnit\Framework\Attributes\DataProvider; | ||
use PHPUnit\Framework\MockObject\MockObject; | ||
use PHPUnit\Framework\TestCase; | ||
use Swag\Braintree\Command\ManifestGenerateCommand; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Twig\Environment; | ||
|
||
#[CoversClass(ManifestGenerateCommand::class)] | ||
class ManifestGenerateCommandTest extends TestCase | ||
{ | ||
private Environment&MockObject $twig; | ||
|
||
private InputInterface&MockObject $input; | ||
|
||
private OutputInterface&MockObject $output; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->twig = $this->createMock(Environment::class); | ||
$this->input = $this->createMock(InputInterface::class); | ||
$this->output = $this->createMock(OutputInterface::class); | ||
} | ||
|
||
#[DataProvider(methodName: 'provideFailOnAnyParameterMissing')] | ||
public function testFailOnAnyParameterMissing( | ||
?string $appUrl, | ||
?string $appSecret, | ||
?string $environment, | ||
?string $projectDir, | ||
): void { | ||
$this->output | ||
->expects(static::atLeastOnce()) | ||
->method('writeln'); | ||
|
||
$command = $this->createCommand( | ||
$appUrl, | ||
$appSecret, | ||
$environment, | ||
$projectDir, | ||
); | ||
|
||
static::assertSame(ManifestGenerateCommand::FAILURE, $command->run($this->input, $this->output)); | ||
} | ||
|
||
public static function provideFailOnAnyParameterMissing(): \Generator | ||
{ | ||
yield 'appUrl missing' => [null, 'appSecret', 'environment', 'projectDir']; | ||
yield 'appSecret missing' => ['appUrl', null, 'environment', 'projectDir']; | ||
yield 'environment missing' => ['appUrl', 'appSecret', null, 'projectDir']; | ||
yield 'projectDir missing' => ['appUrl', 'appSecret', 'environment', null]; | ||
|
||
yield 'appUrl and appSecret missing' => [null, null, 'environment', 'projectDir']; | ||
yield 'appUrl and environment missing' => [null, 'appSecret', null, 'projectDir']; | ||
yield 'appUrl and projectDir missing' => [null, 'appSecret', 'environment', null]; | ||
yield 'appSecret and environment missing' => ['appUrl', null, null, 'projectDir']; | ||
yield 'appSecret and projectDir missing' => ['appUrl', null, 'environment', null]; | ||
yield 'environment and projectDir missing' => ['appUrl', 'appSecret', null, null]; | ||
|
||
yield 'only appUrl' => ['appUrl', null, null, null]; | ||
yield 'only appSecret' => [null, 'appSecret', null, null]; | ||
yield 'only environment' => [null, null, 'environment', null]; | ||
yield 'only projectDir' => [null, null, null, 'projectDir']; | ||
|
||
yield 'all missing' => [null, null, null, null]; | ||
} | ||
|
||
public function testRender(): void | ||
{ | ||
$this->output | ||
->expects(static::never()) | ||
->method('writeln'); | ||
|
||
$this->twig | ||
->expects(static::once()) | ||
->method('render') | ||
->willReturn('manifest'); | ||
|
||
$command = $this->createCommand(); | ||
|
||
$command->expects(static::once())->method('manifestExists')->willReturn(false); | ||
$command->expects(static::once())->method('writeManifest')->willReturn(true); | ||
|
||
static::assertSame(ManifestGenerateCommand::SUCCESS, $command->run($this->input, $this->output)); | ||
} | ||
|
||
public function testRenderUnsuccessfulWrite(): void | ||
{ | ||
$this->output | ||
->expects(static::atLeastOnce()) | ||
->method('writeln'); | ||
|
||
$this->twig | ||
->expects(static::once()) | ||
->method('render') | ||
->willReturn('manifest'); | ||
|
||
$command = $this->createCommand(); | ||
|
||
$command->expects(static::once())->method('manifestExists')->willReturn(false); | ||
$command->expects(static::once())->method('writeManifest')->willReturn(false); | ||
|
||
static::assertSame(ManifestGenerateCommand::FAILURE, $command->run($this->input, $this->output)); | ||
} | ||
|
||
public function testManifestExists(): void | ||
{ | ||
$this->input | ||
->expects(static::once()) | ||
->method('getOption') | ||
->with('force') | ||
->willReturn(false); | ||
|
||
$command = $this->createCommand(); | ||
|
||
$command->expects(static::once())->method('manifestExists')->willReturn(true); | ||
$command->expects(static::never())->method('writeManifest'); | ||
|
||
static::assertSame(ManifestGenerateCommand::SUCCESS, $command->run($this->input, $this->output)); | ||
} | ||
|
||
public function testManifestExistsWithForce(): void | ||
{ | ||
$this->input | ||
->expects(static::once()) | ||
->method('getOption') | ||
->with('force') | ||
->willReturn(true); | ||
|
||
$this->output | ||
->expects(static::never()) | ||
->method('writeln'); | ||
|
||
$this->twig | ||
->expects(static::once()) | ||
->method('render') | ||
->willReturn('manifest'); | ||
|
||
$command = $this->createCommand(); | ||
|
||
$command->expects(static::once())->method('manifestExists')->willReturn(true); | ||
$command->expects(static::once())->method('writeManifest')->willReturn(true); | ||
|
||
static::assertSame(ManifestGenerateCommand::SUCCESS, $command->run($this->input, $this->output)); | ||
} | ||
|
||
protected function createCommand( | ||
?string $appUrl = 'appUrl', | ||
?string $appSecret = 'appSecret', | ||
?string $environment = 'environment', | ||
?string $projectDir = 'projectDir', | ||
): ManifestGenerateCommand&MockObject { | ||
return $this->getMockBuilder(ManifestGenerateCommand::class) | ||
->onlyMethods(['manifestExists', 'writeManifest']) | ||
->setConstructorArgs([$appUrl, $appSecret, $environment, $projectDir, $this->twig]) | ||
->getMock(); | ||
} | ||
} |