From 83181a06384d187bf2bea0950f828c0863ac7183 Mon Sep 17 00:00:00 2001 From: Tomasz Smolarek <59400506+dyfero@users.noreply.github.com> Date: Fri, 8 Sep 2023 12:40:14 +0200 Subject: [PATCH] Add video email templates (#76) Co-authored-by: Tomasz Smolarek --- composer.json | 1 + ...EscolaLmsTemplatesEmailServiceProvider.php | 6 + .../VideoTemplatesServiceProvider.php | 43 +++++++ src/Video/CommonVideoVariables.php | 63 ++++++++++ src/Video/VideoProcessFailedVariables.php | 19 +++ src/Video/VideoProcessFinishedVariables.php | 19 +++ src/Video/VideoProcessStartedVariables.php | 19 +++ src/Video/VideoProcessStateVariables.php | 41 +++++++ tests/Feature/VideoTest.php | 111 ++++++++++++++++++ 9 files changed, 322 insertions(+) create mode 100644 src/Providers/VideoTemplatesServiceProvider.php create mode 100644 src/Video/CommonVideoVariables.php create mode 100644 src/Video/VideoProcessFailedVariables.php create mode 100644 src/Video/VideoProcessFinishedVariables.php create mode 100644 src/Video/VideoProcessStartedVariables.php create mode 100644 src/Video/VideoProcessStateVariables.php create mode 100644 tests/Feature/VideoTest.php diff --git a/composer.json b/composer.json index 63fdc7c..9b41230 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "escolalms/tasks": "^0", "escolalms/topic-type-project": "^0", "escolalms/assign-without-account": "^0", + "escolalms/video": "^0", "orchestra/testbench": "^5.0|^6.0", "phpunit/phpunit": "^9.0" }, diff --git a/src/EscolaLmsTemplatesEmailServiceProvider.php b/src/EscolaLmsTemplatesEmailServiceProvider.php index b15e770..4e07b77 100644 --- a/src/EscolaLmsTemplatesEmailServiceProvider.php +++ b/src/EscolaLmsTemplatesEmailServiceProvider.php @@ -29,12 +29,14 @@ use EscolaLms\TemplatesEmail\Providers\TaskTemplatesServiceProvider; use EscolaLms\TemplatesEmail\Providers\TemplateServiceProvider; use EscolaLms\TemplatesEmail\Providers\TopicTypeProjectTemplatesServiceProvider; +use EscolaLms\TemplatesEmail\Providers\VideoTemplatesServiceProvider; use EscolaLms\TemplatesEmail\Providers\WebinarTemplatesServiceProvider; use EscolaLms\TemplatesEmail\Providers\YoutubeTemplatesServiceProvider; use EscolaLms\TemplatesEmail\Rules\MjmlRule; use EscolaLms\TemplatesEmail\Services\Contracts\MjmlServiceContract; use EscolaLms\TemplatesEmail\Services\MjmlService; use EscolaLms\TopicTypeProject\EscolaLmsTopicTypeProjectServiceProvider; +use EscolaLms\Video\EscolaLmsVideoServiceProvider; use EscolaLms\Webinar\EscolaLmsWebinarServiceProvider; use EscolaLms\Youtube\EscolaLmsYoutubeServiceProvider; use Illuminate\Support\ServiceProvider; @@ -105,6 +107,10 @@ class_exists(EscolaLmsTemplatesServiceProvider::class) && $this->app->register(TopicTypeProjectTemplatesServiceProvider::class); } + if (class_exists(EscolaLmsVideoServiceProvider::class)) { + $this->app->register(VideoTemplatesServiceProvider::class); + } + $this->app->register(TemplateServiceProvider::class); $this->loadViewsFrom(__DIR__.'/../resources/views', 'templates-email'); diff --git a/src/Providers/VideoTemplatesServiceProvider.php b/src/Providers/VideoTemplatesServiceProvider.php new file mode 100644 index 0000000..a7f3960 --- /dev/null +++ b/src/Providers/VideoTemplatesServiceProvider.php @@ -0,0 +1,43 @@ + $faker->word, + self::VAR_TOPIC_TITLE => $faker->word, + ]); + } + + public static function variablesFromEvent(EventWrapper $event): array + { + return array_merge(parent::variablesFromEvent($event), [ + self::VAR_USER_NAME => $event->getUser()->name, + self::VAR_TOPIC_TITLE => $event->getTopic()->title, + ]); + } + + public static function defaultSectionsContent(): array + { + return [ + 'title' => '', + 'content' => '' + ]; + } + + public static function assignableClass(): ?string + { + return null; + } + + public static function requiredVariables(): array + { + return [ + self::VAR_TOPIC_TITLE + ]; + } + + public static function requiredVariablesInSection(string $sectionKey): array + { + if ($sectionKey === 'content') { + return [ + self::VAR_TOPIC_TITLE, + ]; + } + + return []; + } +} diff --git a/src/Video/VideoProcessFailedVariables.php b/src/Video/VideoProcessFailedVariables.php new file mode 100644 index 0000000..df91748 --- /dev/null +++ b/src/Video/VideoProcessFailedVariables.php @@ -0,0 +1,19 @@ + __('Video processing progress failed for topic - :topic', [ + 'topic' => self::VAR_TOPIC_TITLE + ]), + 'content' => self::wrapWithMjml(__('

Hello :user_name!

Your video in topic :topic was not processed successfully.

', [ + 'user_name' => self::VAR_USER_NAME, + 'topic' => self::VAR_TOPIC_TITLE, + ])), + ]; + } +} diff --git a/src/Video/VideoProcessFinishedVariables.php b/src/Video/VideoProcessFinishedVariables.php new file mode 100644 index 0000000..019677f --- /dev/null +++ b/src/Video/VideoProcessFinishedVariables.php @@ -0,0 +1,19 @@ + __('Video processing finished for topic - :topic', [ + 'topic' => self::VAR_TOPIC_TITLE + ]), + 'content' => self::wrapWithMjml(__('

Hello :user_name!

Your video in topic :topic has been processed successfully!

', [ + 'user_name' => self::VAR_USER_NAME, + 'topic' => self::VAR_TOPIC_TITLE, + ])), + ]; + } +} diff --git a/src/Video/VideoProcessStartedVariables.php b/src/Video/VideoProcessStartedVariables.php new file mode 100644 index 0000000..d4ff136 --- /dev/null +++ b/src/Video/VideoProcessStartedVariables.php @@ -0,0 +1,19 @@ + __('Video processing progress starting for topic - :topic', [ + 'topic' => self::VAR_TOPIC_TITLE + ]), + 'content' => self::wrapWithMjml(__('

Hello :user_name!

The processing of your video has started for topic - :topic.

', [ + 'user_name' => self::VAR_USER_NAME, + 'topic' => self::VAR_TOPIC_TITLE, + ])), + ]; + } +} diff --git a/src/Video/VideoProcessStateVariables.php b/src/Video/VideoProcessStateVariables.php new file mode 100644 index 0000000..f912e6b --- /dev/null +++ b/src/Video/VideoProcessStateVariables.php @@ -0,0 +1,41 @@ + $faker->numberBetween(0, 100), + ]); + } + + public static function variablesFromEvent(EventWrapper $event): array + { + return array_merge(parent::variablesFromEvent($event), [ + self::VAR_VIDEO_PERCENTAGE => $event->getPercentage(), + ]); + } + + public static function defaultSectionsContent(): array + { + return [ + 'title' => __('Video processing progress update for topic - :topic - :percentage%', [ + 'topic' => self::VAR_TOPIC_TITLE, + 'percentage' => self::VAR_VIDEO_PERCENTAGE, + ]), + 'content' => self::wrapWithMjml(__('

Hello :user_name!

The progress of processing your video in :topic is currently :percentage%.

', [ + 'user_name' => self::VAR_USER_NAME, + 'percentage' => self::VAR_VIDEO_PERCENTAGE, + 'topic' => self::VAR_TOPIC_TITLE, + ])), + ]; + } +} diff --git a/tests/Feature/VideoTest.php b/tests/Feature/VideoTest.php new file mode 100644 index 0000000..74e149f --- /dev/null +++ b/tests/Feature/VideoTest.php @@ -0,0 +1,111 @@ +makeInstructor(); + $topic = $this->createTopicVideo(); + + Event::dispatch(new ProcessVideoStarted($tutor, $topic)); + + Mail::assertSent(EmailMailable::class, function (EmailMailable $mailable) use ($topic, $tutor) { + $this->assertTrue($mailable->hasTo($tutor->email)); + $this->assertEquals(__('Video processing progress starting for topic - :topic', ['topic' => $topic->title]), $mailable->subject); + $this->assertStringContainsString($tutor->name, $mailable->getHtml()); + $this->assertStringContainsString($topic->title, $mailable->getHtml()); + + return true; + }); + } + public function testNotificationSentWhenVideoProcessingSucceed(): void + { + Mail::fake(); + + $tutor = $this->makeInstructor(); + $topic = $this->createTopicVideo(); + + Event::dispatch(new ProcessVideoFinished($tutor, $topic)); + + Mail::assertSent(EmailMailable::class, function (EmailMailable $mailable) use ($topic, $tutor) { + $this->assertTrue($mailable->hasTo($tutor->email)); + $this->assertEquals(__('Video processing finished for topic - :topic', ['topic' => $topic->title]), $mailable->subject); + $this->assertStringContainsString($tutor->name, $mailable->getHtml()); + $this->assertStringContainsString($topic->title, $mailable->getHtml()); + + return true; + }); + } + + public function testNotificationSentWhenVideoProcessingFailed(): void + { + Mail::fake(); + + $tutor = $this->makeInstructor(); + $topic = $this->createTopicVideo(); + + Event::dispatch(new ProcessVideoFailed($tutor, $topic)); + + Mail::assertSent(EmailMailable::class, function (EmailMailable $mailable) use ($topic, $tutor) { + $this->assertTrue($mailable->hasTo($tutor->email)); + $this->assertEquals(__('Video processing progress failed for topic - :topic', ['topic' => $topic->title]), $mailable->subject); + $this->assertStringContainsString($tutor->name, $mailable->getHtml()); + $this->assertStringContainsString($topic->title, $mailable->getHtml()); + + return true; + }); + } + + public function testNotificationSentWhenVideoProcessingState(): void + { + Mail::fake(); + + $tutor = $this->makeInstructor(); + $topic = $this->createTopicVideo(); + + Event::dispatch(new ProcessVideoState($tutor, $topic, 60)); + + Mail::assertSent(EmailMailable::class, function (EmailMailable $mailable) use ($topic, $tutor) { + $this->assertTrue($mailable->hasTo($tutor->email)); + $this->assertEquals(__('Video processing progress update for topic - :topic - :percentage%', ['topic' => $topic->title, 'percentage' => 60]), $mailable->subject); + $this->assertStringContainsString('60%', $mailable->getHtml()); + $this->assertStringContainsString($tutor->name, $mailable->getHtml()); + $this->assertStringContainsString($topic->title, $mailable->getHtml()); + + return true; + }); + } + + private function createTopicVideo(): Topic + { + /** @var Topic */ + return Topic::factory() + ->for(Lesson::factory()->for(Course::factory())) + ->state(fn() => [ + 'topicable_type' => \EscolaLms\TopicTypes\Models\TopicContent\Video::class, + 'topicable_id' => Video::factory()->create()->getKey() + ]) + ->create(); + } +}