Skip to content

Commit

Permalink
Add somake:notification command (#49)
Browse files Browse the repository at this point in the history
* Add somake:notification command

* Update README

* Multilingual is now enabled by default

* Add a pre-filled unit test for notifications

* Delete 'ConvertModels.php' file in test-laravel

* use trans() function

* use pest expectation api

* Add a test for the via() method

* Simplified verification for notification testing
  • Loading branch information
EdenMl authored Dec 5, 2023
1 parent dc39563 commit e47f485
Showing 13 changed files with 302 additions and 10 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -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

1 change: 1 addition & 0 deletions config/somake.php
Original file line number Diff line number Diff line change
@@ -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,
],
];
34 changes: 34 additions & 0 deletions resources/views/notification.blade.php
Original file line number Diff line number Diff line change
@@ -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>|string
*/
public function via(): array|string
{
return ['mail'];
}

public function toMail(): MailMessage
{
return (new MailMessage())
->subject(trans('Welcome to our platform'));
}
}
24 changes: 24 additions & 0 deletions resources/views/test-unit-notification.blade.php
Original file line number Diff line number Diff line change
@@ -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('');
});
48 changes: 48 additions & 0 deletions src/Commands/NotificationCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php declare(strict_types=1);

namespace Soyhuce\Somake\Commands;

use Illuminate\Console\Command;
use Soyhuce\Somake\Commands\Concerns\AsksDomain;
use Soyhuce\Somake\Commands\Concerns\CreatesAssociatedUnitTest;
use Soyhuce\Somake\Support\Finder;
use Soyhuce\Somake\Support\Writer;
use function Laravel\Prompts\outro;
use function Laravel\Prompts\text;

class NotificationCommand extends Command
{
use AsksDomain;
use CreatesAssociatedUnitTest;

/** @var string */
public $signature = 'somake:notification';

/** @var string */
public $description = 'Generates a Notification in Domain';

public function handle(Finder $finder, Writer $writer): void
{
$notification = text(label: 'What is the Notification name ?', required: true);

$queued = $this->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);
}
}
27 changes: 27 additions & 0 deletions src/Domains/Test/UnitTestGenerators/NotificationTestGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);

namespace Soyhuce\Somake\Domains\Test\UnitTestGenerators;

use Illuminate\Notifications\Notification;
use Soyhuce\Somake\Contracts\UnitTestGenerator;

/**
* @implements \Soyhuce\Somake\Contracts\UnitTestGenerator<mixed>
*/
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 [];
}
}
2 changes: 2 additions & 0 deletions src/SomakeServiceProvider.php
Original file line number Diff line number Diff line change
@@ -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,
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php declare(strict_types=1);

namespace Domain\User\Notifications;

use Domain\User\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class AccountCreatedNotification extends Notification
{
/**
* @return array<string>|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('/'));
}
}
31 changes: 31 additions & 0 deletions tests/Feature/NotificationCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types=1);

it('creates the notification correctly', function (): void {
$this->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();
});
13 changes: 13 additions & 0 deletions tests/Feature/TestCommandTest.php
Original file line number Diff line number Diff line change
@@ -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();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Domain\User\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class WelcomeNotification extends Notification implements ShouldQueue
{
use Queueable;

public function __construct()
{
}

/**
* @return array<string>|string
*/
public function via(): array|string
{
return ['mail'];
}

public function toMail(): MailMessage
{
return (new MailMessage())
->subject(trans('Welcome to our platform'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Domain\User\Notifications;

use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class WelcomeNotification extends Notification
{
public function __construct()
{
}

/**
* @return array<string>|string
*/
public function via(): array|string
{
return ['mail'];
}

public function toMail(): MailMessage
{
return (new MailMessage())
->subject(trans('Welcome to our platform'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/* @covers \Domain\User\Notifications\AccountCreatedNotification */

use Domain\User\Notifications\AccountCreatedNotification;
use Illuminate\Notifications\Messages\MailMessage;

it('uses the mail channel', function (): void {
$notification = new AccountCreatedNotification();

expect($notification->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('');
});

0 comments on commit e47f485

Please sign in to comment.