diff --git a/README.md b/README.md index 815ed8c..1f80896 100644 --- a/README.md +++ b/README.md @@ -46,16 +46,17 @@ The configuration of generated classes is done via interactive questions. ### Domain -| Commande | Description | Generation path | -|-------------------|------------------|---------------------------------| -| `somake:action` | Action | `app/Domain/[domain]/Actions` | -| `somake:builder` | Eloquent Builder | `app/Domain/[domain]/Builders` | -| `somake:data` | Data | `app/Domain/[domain]/Data` | -| `somake:enum` | Enum | `app/Domain/[domain]/Enums` | -| `somake:event` | Event | `app/Domain/[domain]/Events` | -| `somake:listener` | Listener | `app/Domain/[domain]/Listeners` | -| `somake:model` | Model | `app/Domain/[domain]/Models` | -| `somake:policy` | Policy | `app/Domain/[domain]/Policies` | +| Commande | Description | Generation path | +|-----------------------|------------------|-------------------------------------| +| `somake:action` | Action | `app/Domain/[domain]/Actions` | +| `somake:builder` | Eloquent Builder | `app/Domain/[domain]/Builders` | +| `somake:data` | Data | `app/Domain/[domain]/Data` | +| `somake:enum` | Enum | `app/Domain/[domain]/Enums` | +| `somake:event` | Event | `app/Domain/[domain]/Events` | +| `somake:listener` | Listener | `app/Domain/[domain]/Listeners` | +| `somake:model` | Model | `app/Domain/[domain]/Models` | +| `somake:notification` | Notification | `app/Domain/[domain]/Notifications` | +| `somake:policy` | Policy | `app/Domain/[domain]/Policies` | ### Support diff --git a/config/somake.php b/config/somake.php index 96f02cb..95f7ab1 100644 --- a/config/somake.php +++ b/config/somake.php @@ -23,6 +23,7 @@ Soyhuce\Somake\Domains\Test\UnitTestGenerators\ListenerTestGenerator::class, Soyhuce\Somake\Domains\Test\UnitTestGenerators\JsonResourceTestGenerator::class, Soyhuce\Somake\Domains\Test\UnitTestGenerators\MiddlewareTestGenerator::class, + Soyhuce\Somake\Domains\Test\UnitTestGenerators\NotificationTestGenerator::class, Soyhuce\Somake\Domains\Test\UnitTestGenerators\DefaultTestGenerator::class, ], ]; diff --git a/resources/views/notification.blade.php b/resources/views/notification.blade.php new file mode 100644 index 0000000..9919f51 --- /dev/null +++ b/resources/views/notification.blade.php @@ -0,0 +1,34 @@ +namespace {{ $namespace }}; + +use Illuminate\Notifications\Notification; +use Illuminate\Notifications\Messages\MailMessage; +@if($queued) +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +@endif + +class {{ $notification }} extends Notification @if($queued)implements ShouldQueue @endif + +{ +@if($queued) + use Queueable; + +@endif + public function __construct() + { + } + + /** + * @return array|string + */ + public function via(): array|string + { + return ['mail']; + } + + public function toMail(): MailMessage + { + return (new MailMessage()) + ->subject(trans('Welcome to our platform')); + } +} diff --git a/resources/views/test-unit-notification.blade.php b/resources/views/test-unit-notification.blade.php new file mode 100644 index 0000000..8b92a79 --- /dev/null +++ b/resources/views/test-unit-notification.blade.php @@ -0,0 +1,24 @@ +/* @@covers \{{ $covered }} */ + +use {{ $classFqcn }}; +use Illuminate\Notifications\Messages\MailMessage; + +it('uses the mail channel', function (): void { + $notification = new {{ $classBasename }}(); + + expect($notification->via())->toBe(['mail']); +}); + +it('formats the mail', function (): void { + $mail = (new {{ $classBasename }}())->toMail(); + + expect($mail) + ->toBeInstanceOf(MailMessage::class) + ->subject->toBe('') + ->greeting->toBe('') + ->introLines->toBe(['']) + ->actionText->toBe('') + ->actionUrl->toBeUrl()->toBe('') + ->outroLines->toBe(['']) + ->salutation->toBe(''); +}); \ No newline at end of file diff --git a/src/Commands/NotificationCommand.php b/src/Commands/NotificationCommand.php new file mode 100644 index 0000000..2ffea20 --- /dev/null +++ b/src/Commands/NotificationCommand.php @@ -0,0 +1,48 @@ +confirm(question: 'Should the notification be queued ?'); + + $domain = $this->askDomain($finder->domains()); + + $writer + ->write( + 'notification', + [ + 'notification' => $notification, + 'queued' => $queued, + ] + ) + ->toPath($finder->domainPath("{$domain}/Notifications/{$notification}.php")); + + $notificationFqcn = "Domain\\{$domain}\\Notifications\\{$notification}"; + + outro("The {$notificationFqcn} class was successfully created !"); + + $this->createUnitTest($notificationFqcn); + } +} diff --git a/src/Domains/Test/UnitTestGenerators/NotificationTestGenerator.php b/src/Domains/Test/UnitTestGenerators/NotificationTestGenerator.php new file mode 100644 index 0000000..7e0d7b2 --- /dev/null +++ b/src/Domains/Test/UnitTestGenerators/NotificationTestGenerator.php @@ -0,0 +1,27 @@ + + */ +class NotificationTestGenerator implements UnitTestGenerator +{ + public static function shouldHandle(string $class): bool + { + return is_subclass_of($class, Notification::class); + } + + public function view(): string + { + return 'test-unit-notification'; + } + + public function data(string $class): array + { + return []; + } +} diff --git a/src/SomakeServiceProvider.php b/src/SomakeServiceProvider.php index ea8fcd0..e565e9a 100644 --- a/src/SomakeServiceProvider.php +++ b/src/SomakeServiceProvider.php @@ -16,6 +16,7 @@ use Soyhuce\Somake\Commands\MiddlewareCommand; use Soyhuce\Somake\Commands\MigrationCommand; use Soyhuce\Somake\Commands\ModelCommand; +use Soyhuce\Somake\Commands\NotificationCommand; use Soyhuce\Somake\Commands\PolicyCommand; use Soyhuce\Somake\Commands\ProviderCommand; use Soyhuce\Somake\Commands\RequestCommand; @@ -48,6 +49,7 @@ public function configurePackage(Package $package): void MiddlewareCommand::class, MigrationCommand::class, ModelCommand::class, + NotificationCommand::class, PolicyCommand::class, ProviderCommand::class, RequestCommand::class, diff --git a/test-laravel/app/Domain/User/Notifications/AccountCreatedNotification.php b/test-laravel/app/Domain/User/Notifications/AccountCreatedNotification.php new file mode 100644 index 0000000..21ff071 --- /dev/null +++ b/test-laravel/app/Domain/User/Notifications/AccountCreatedNotification.php @@ -0,0 +1,27 @@ +|string + */ + public function via(): array|string + { + return ['mail']; + } + + public function toMail(User $user): MailMessage + { + return (new MailMessage()) + ->greeting(trans('Hello :name,', ['name' => $user->name])) + ->subject(trans('Your account has been created')) + ->line(trans('Your account has been created, you can now connect to the platform using your usual credentials.')) + ->action(trans('Connect'), url('/')); + } +} diff --git a/tests/Feature/NotificationCommandTest.php b/tests/Feature/NotificationCommandTest.php new file mode 100644 index 0000000..9b3b337 --- /dev/null +++ b/tests/Feature/NotificationCommandTest.php @@ -0,0 +1,31 @@ +artisan('somake:notification') + ->expectsQuestion('What is the Notification name ?', 'WelcomeNotification') + ->expectsQuestion('Should the notification be queued ?', true) + ->expectsQuestion('What is the Domain ?', 'User') + ->expectsOutputToContain('The Domain\\User\\Notifications\\WelcomeNotification class was successfully created !') + ->expectsQuestion('Do you want to create a Unit Test for Domain\User\Notifications\WelcomeNotification ?', false) + ->assertExitCode(0) + ->execute(); + + expect($this->app->basePath('app/Domain/User/Notifications/WelcomeNotification.php')) + ->toBeFile() + ->toMatchFileSnapshot(); +}); + +it('creates the notification not queued', function (): void { + $this->artisan('somake:notification') + ->expectsQuestion('What is the Notification name ?', 'WelcomeNotification') + ->expectsQuestion('Should the notification be queued ?', false) + ->expectsQuestion('What is the Domain ?', 'User') + ->expectsOutputToContain('The Domain\\User\\Notifications\\WelcomeNotification class was successfully created !') + ->expectsQuestion('Do you want to create a Unit Test for Domain\User\Notifications\WelcomeNotification ?', false) + ->assertExitCode(0) + ->execute(); + + expect($this->app->basePath('app/Domain/User/Notifications/WelcomeNotification.php')) + ->toBeFile() + ->toMatchFileSnapshot(); +}); diff --git a/tests/Feature/TestCommandTest.php b/tests/Feature/TestCommandTest.php index 77f7385..8e93581 100644 --- a/tests/Feature/TestCommandTest.php +++ b/tests/Feature/TestCommandTest.php @@ -132,3 +132,16 @@ ->toBeFile() ->toMatchFileSnapshot(); }); + +it('creates correctly the unit test for notification', function (): void { + $this->artisan('somake:test') + ->expectsQuestion('Which kind of test do you want to create ?', 'Unit') + ->expectsQuestion('Which class do you want to cover ?', 'AccountCreatedNotification') + ->expectsOutputToContain('The Tests\\Unit\\Domain\\User\\Notifications\\AccountCreatedNotificationTest class was successfully created !') + ->assertExitCode(0) + ->execute(); + + expect($this->app->basePath('tests/Unit/Domain/User/Notifications/AccountCreatedNotificationTest.php')) + ->toBeFile() + ->toMatchFileSnapshot(); +}); diff --git a/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_correctly__1.php b/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_correctly__1.php new file mode 100644 index 0000000..e0c8b70 --- /dev/null +++ b/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_correctly__1.php @@ -0,0 +1,31 @@ +|string + */ + public function via(): array|string + { + return ['mail']; + } + + public function toMail(): MailMessage + { + return (new MailMessage()) + ->subject(trans('Welcome to our platform')); + } +} diff --git a/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_not_queued__1.php b/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_not_queued__1.php new file mode 100644 index 0000000..2799c4a --- /dev/null +++ b/tests/__snapshots__/files/NotificationCommandTest__it_creates_the_notification_not_queued__1.php @@ -0,0 +1,27 @@ +|string + */ + public function via(): array|string + { + return ['mail']; + } + + public function toMail(): MailMessage + { + return (new MailMessage()) + ->subject(trans('Welcome to our platform')); + } +} diff --git a/tests/__snapshots__/files/TestCommandTest__it_creates_correctly_the_unit_test_for_notification__1.php b/tests/__snapshots__/files/TestCommandTest__it_creates_correctly_the_unit_test_for_notification__1.php new file mode 100644 index 0000000..343355b --- /dev/null +++ b/tests/__snapshots__/files/TestCommandTest__it_creates_correctly_the_unit_test_for_notification__1.php @@ -0,0 +1,26 @@ +via())->toBe(['mail']); +}); + +it('formats the mail', function (): void { + $mail = (new AccountCreatedNotification())->toMail(); + + expect($mail) + ->toBeInstanceOf(MailMessage::class) + ->subject->toBe('') + ->greeting->toBe('') + ->introLines->toBe(['']) + ->actionText->toBe('') + ->actionUrl->toBeUrl()->toBe('') + ->outroLines->toBe(['']) + ->salutation->toBe(''); +}); \ No newline at end of file