Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117873706
D3590.1775332865.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
26 KB
Referenced Files
None
Subscribers
None
D3590.1775332865.diff
View Options
diff --git a/src/.env.example b/src/.env.example
--- a/src/.env.example
+++ b/src/.env.example
@@ -172,3 +172,4 @@
KB_ACCOUNT_DELETE=
KB_ACCOUNT_SUSPENDED=
+KB_PAYMENT_SYSTEM=
diff --git a/src/app/Console/Commands/Wallet/TrialEndCommand.php b/src/app/Console/Commands/Wallet/TrialEndCommand.php
new file mode 100644
--- /dev/null
+++ b/src/app/Console/Commands/Wallet/TrialEndCommand.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Console\Commands\Wallet;
+
+use App\Console\Command;
+
+class TrialEndCommand extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'wallet:trial-end';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Notify wallet (account) owners about an end of the trial period.';
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ // Get all wallets, excluding deleted/inactive accounts
+ // created precisely a month ago
+ $wallets = \App\Wallet::select('wallets.*')
+ ->join('users', 'users.id', '=', 'wallets.user_id')
+ ->leftJoin('wallet_settings', function ($join) {
+ $join->on('wallet_settings.wallet_id', '=', 'wallets.id')
+ ->where('wallet_settings.key', 'trial_end_notice');
+ })
+ ->withEnvTenantContext('users')
+ ->whereNull('users.deleted_at')
+ ->where('users.status', '&', \App\User::STATUS_IMAP_READY)
+ ->where('users.created_at', '>', \now()->subMonthsNoOverflow(2))
+ ->whereNull('wallet_settings.value')
+ ->cursor();
+
+ foreach ($wallets as $wallet) {
+ // Send the email asynchronously
+ \App\Jobs\TrialEndEmail::dispatch($wallet->owner);
+
+ // Store the timestamp
+ $wallet->setSetting('trial_end_notice', (string) \now());
+ }
+ }
+}
diff --git a/src/app/Console/Kernel.php b/src/app/Console/Kernel.php
--- a/src/app/Console/Kernel.php
+++ b/src/app/Console/Kernel.php
@@ -16,25 +16,20 @@
*/
protected function schedule(Schedule $schedule)
{
- // This command imports countries and the current set of IPv4 and IPv6 networks allocated to countries.
+ // This imports countries and the current set of IPv4 and IPv6 networks allocated to countries.
$schedule->command('data:import')->dailyAt('05:00');
// This notifies users about coming password expiration
$schedule->command('password:retention')->dailyAt('06:00');
- // These apply wallet charges
- $schedule->command('wallet:charge')->dailyAt('00:00');
- $schedule->command('wallet:charge')->dailyAt('04:00');
- $schedule->command('wallet:charge')->dailyAt('08:00');
- $schedule->command('wallet:charge')->dailyAt('12:00');
- $schedule->command('wallet:charge')->dailyAt('16:00');
- $schedule->command('wallet:charge')->dailyAt('20:00');
+ // This applies wallet charges
+ $schedule->command('wallet:charge')->everyFourHours();
- // this is a laravel 8-ism
- //$schedule->command('wallet:charge')->everyFourHours();
-
- // This command removes deleted storage files/file chunks from the filesystem
+ // This removes deleted storage files/file chunks from the filesystem
$schedule->command('fs:expunge')->hourly();
+
+ // This notifies users about an end of the trial period
+ $schedule->command('wallet:trial-end')->dailyAt('07:00');
}
/**
diff --git a/src/app/Jobs/TrialEndEmail.php b/src/app/Jobs/TrialEndEmail.php
new file mode 100644
--- /dev/null
+++ b/src/app/Jobs/TrialEndEmail.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace App\Jobs;
+
+use App\Mail\TrialEnd;
+use App\User;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Queue\InteractsWithQueue;
+
+class TrialEndEmail implements ShouldQueue
+{
+ use Dispatchable;
+ use InteractsWithQueue;
+ use Queueable;
+ use SerializesModels;
+
+ /** @var int The number of times the job may be attempted. */
+ public $tries = 3;
+
+ /** @var bool Delete the job if its models no longer exist. */
+ public $deleteWhenMissingModels = true;
+
+ /** @var \App\User The account owner */
+ protected $account;
+
+ /**
+ * Create a new job instance.
+ *
+ * @param \App\User $account The account owner
+ *
+ * @return void
+ */
+ public function __construct(User $account)
+ {
+ $this->account = $account;
+ }
+
+ /**
+ * Determine the time at which the job should timeout.
+ *
+ * @return \DateTime
+ */
+ public function retryUntil()
+ {
+ // FIXME: I think it does not make sense to continue trying after 24 hours
+ return now()->addHours(24);
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ \App\Mail\Helper::sendMail(
+ new TrialEnd($this->account),
+ $this->account->tenant_id,
+ ['to' => $this->account->email]
+ );
+ }
+}
diff --git a/src/app/Mail/DegradedAccountReminder.php b/src/app/Mail/DegradedAccountReminder.php
--- a/src/app/Mail/DegradedAccountReminder.php
+++ b/src/app/Mail/DegradedAccountReminder.php
@@ -55,7 +55,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
'dashboardUrl' => Utils::serviceUrl('/dashboard', $this->user->tenant_id),
]);
diff --git a/src/app/Mail/NegativeBalance.php b/src/app/Mail/NegativeBalance.php
--- a/src/app/Mail/NegativeBalance.php
+++ b/src/app/Mail/NegativeBalance.php
@@ -55,7 +55,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
]);
diff --git a/src/app/Mail/NegativeBalanceBeforeDelete.php b/src/app/Mail/NegativeBalanceBeforeDelete.php
--- a/src/app/Mail/NegativeBalanceBeforeDelete.php
+++ b/src/app/Mail/NegativeBalanceBeforeDelete.php
@@ -57,7 +57,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
'date' => $threshold->toDateString(),
]);
diff --git a/src/app/Mail/NegativeBalanceDegraded.php b/src/app/Mail/NegativeBalanceDegraded.php
--- a/src/app/Mail/NegativeBalanceDegraded.php
+++ b/src/app/Mail/NegativeBalanceDegraded.php
@@ -56,7 +56,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
]);
diff --git a/src/app/Mail/NegativeBalanceReminder.php b/src/app/Mail/NegativeBalanceReminder.php
--- a/src/app/Mail/NegativeBalanceReminder.php
+++ b/src/app/Mail/NegativeBalanceReminder.php
@@ -57,7 +57,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
'date' => $threshold->toDateString(),
]);
diff --git a/src/app/Mail/NegativeBalanceReminderDegrade.php b/src/app/Mail/NegativeBalanceReminderDegrade.php
--- a/src/app/Mail/NegativeBalanceReminderDegrade.php
+++ b/src/app/Mail/NegativeBalanceReminderDegrade.php
@@ -57,7 +57,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
'date' => $threshold->toDateString(),
]);
diff --git a/src/app/Mail/NegativeBalanceSuspended.php b/src/app/Mail/NegativeBalanceSuspended.php
--- a/src/app/Mail/NegativeBalanceSuspended.php
+++ b/src/app/Mail/NegativeBalanceSuspended.php
@@ -57,7 +57,7 @@
'site' => $appName,
'subject' => $subject,
'username' => $this->user->name(true),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
'date' => $threshold->toDateString(),
]);
diff --git a/src/app/Mail/PasswordExpirationReminder.php b/src/app/Mail/PasswordExpirationReminder.php
--- a/src/app/Mail/PasswordExpirationReminder.php
+++ b/src/app/Mail/PasswordExpirationReminder.php
@@ -44,7 +44,6 @@
public function build()
{
$appName = Tenant::getConfig($this->user->tenant_id, 'app.name');
- $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url');
$href = Utils::serviceUrl('profile', $this->user->tenant_id);
$params = [
diff --git a/src/app/Mail/PasswordReset.php b/src/app/Mail/PasswordReset.php
--- a/src/app/Mail/PasswordReset.php
+++ b/src/app/Mail/PasswordReset.php
@@ -40,7 +40,6 @@
public function build()
{
$appName = Tenant::getConfig($this->code->user->tenant_id, 'app.name');
- $supportUrl = Tenant::getConfig($this->code->user->tenant_id, 'app.support_url');
$href = Utils::serviceUrl(
sprintf('/password-reset/%s-%s', $this->code->short_code, $this->code->code),
diff --git a/src/app/Mail/PaymentFailure.php b/src/app/Mail/PaymentFailure.php
--- a/src/app/Mail/PaymentFailure.php
+++ b/src/app/Mail/PaymentFailure.php
@@ -56,7 +56,7 @@
'subject' => $subject,
'username' => $this->user->name(true),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
]);
return $this;
diff --git a/src/app/Mail/PaymentMandateDisabled.php b/src/app/Mail/PaymentMandateDisabled.php
--- a/src/app/Mail/PaymentMandateDisabled.php
+++ b/src/app/Mail/PaymentMandateDisabled.php
@@ -56,7 +56,7 @@
'subject' => $subject,
'username' => $this->user->name(true),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
]);
return $this;
diff --git a/src/app/Mail/PaymentSuccess.php b/src/app/Mail/PaymentSuccess.php
--- a/src/app/Mail/PaymentSuccess.php
+++ b/src/app/Mail/PaymentSuccess.php
@@ -56,7 +56,7 @@
'subject' => $subject,
'username' => $this->user->name(true),
'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id),
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id),
]);
return $this;
diff --git a/src/app/Mail/SuspendedDebtor.php b/src/app/Mail/SuspendedDebtor.php
--- a/src/app/Mail/SuspendedDebtor.php
+++ b/src/app/Mail/SuspendedDebtor.php
@@ -58,7 +58,7 @@
'subject' => $subject,
'username' => $this->account->name(true),
'cancelUrl' => $cancelUrl,
- 'supportUrl' => $supportUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->account->tenant_id),
'walletUrl' => Utils::serviceUrl('/wallet', $this->account->tenant_id),
'moreInfoHtml' => $moreInfoHtml,
'moreInfoText' => $moreInfoText,
diff --git a/src/app/Mail/SuspendedDebtor.php b/src/app/Mail/TrialEnd.php
copy from src/app/Mail/SuspendedDebtor.php
copy to src/app/Mail/TrialEnd.php
--- a/src/app/Mail/SuspendedDebtor.php
+++ b/src/app/Mail/TrialEnd.php
@@ -9,19 +9,19 @@
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
-class SuspendedDebtor extends Mailable
+class TrialEnd extends Mailable
{
use Queueable;
use SerializesModels;
- /** @var \App\User A suspended user (account) */
+ /** @var \App\User An account owner (account) */
protected $account;
/**
* Create a new message instance.
*
- * @param \App\User $account A suspended user (account)
+ * @param \App\User $account An account owner (account)
*
* @return void
*/
@@ -38,31 +38,20 @@
public function build()
{
$appName = Tenant::getConfig($this->account->tenant_id, 'app.name');
+ $paymentUrl = Tenant::getConfig($this->account->tenant_id, 'app.kb.payment_system');
$supportUrl = Tenant::getConfig($this->account->tenant_id, 'app.support_url');
- $cancelUrl = Tenant::getConfig($this->account->tenant_id, 'app.kb.account_delete');
- $subject = \trans('mail.suspendeddebtor-subject', ['site' => $appName]);
+ $subject = \trans('mail.trialend-subject', ['site' => $appName]);
- $moreInfoHtml = null;
- $moreInfoText = null;
- if ($moreInfoUrl = Tenant::getConfig($this->account->tenant_id, 'app.kb.account_suspended')) {
- $moreInfoHtml = \trans('mail.more-info-html', ['href' => $moreInfoUrl]);
- $moreInfoText = \trans('mail.more-info-text', ['href' => $moreInfoUrl]);
- }
-
- $this->view('emails.html.suspended_debtor')
- ->text('emails.plain.suspended_debtor')
+ $this->view('emails.html.trial_end')
+ ->text('emails.plain.trial_end')
->subject($subject)
->with([
'site' => $appName,
'subject' => $subject,
'username' => $this->account->name(true),
- 'cancelUrl' => $cancelUrl,
- 'supportUrl' => $supportUrl,
- 'walletUrl' => Utils::serviceUrl('/wallet', $this->account->tenant_id),
- 'moreInfoHtml' => $moreInfoHtml,
- 'moreInfoText' => $moreInfoText,
- 'days' => 14 // TODO: Configurable
+ 'paymentUrl' => $paymentUrl,
+ 'supportUrl' => Utils::serviceUrl($supportUrl, $this->account->tenant_id),
]);
return $this;
diff --git a/src/app/Utils.php b/src/app/Utils.php
--- a/src/app/Utils.php
+++ b/src/app/Utils.php
@@ -460,7 +460,7 @@
/**
* Create self URL
*
- * @param string $route Route/Path
+ * @param string $route Route/Path/URL
* @param int|null $tenantId Current tenant
*
* @todo Move this to App\Http\Controllers\Controller
@@ -469,6 +469,10 @@
*/
public static function serviceUrl(string $route, $tenantId = null): string
{
+ if (preg_match('|^https?://|i', $route)) {
+ return $route;
+ }
+
$url = \App\Tenant::getConfig($tenantId, 'app.public_url');
if (!$url) {
diff --git a/src/config/app.php b/src/config/app.php
--- a/src/config/app.php
+++ b/src/config/app.php
@@ -230,6 +230,8 @@
'account_suspended' => env('KB_ACCOUNT_SUSPENDED'),
// An article about a way to delete an owned account
'account_delete' => env('KB_ACCOUNT_DELETE'),
+ // An article about the payment system
+ 'payment_system' => env('KB_PAYMENT_SYSTEM'),
],
'company' => [
diff --git a/src/resources/lang/en/mail.php b/src/resources/lang/en/mail.php
--- a/src/resources/lang/en/mail.php
+++ b/src/resources/lang/en/mail.php
@@ -107,4 +107,17 @@
'suspendeddebtor-middle' => "Settle up now to reactivate your account.",
'suspendeddebtor-cancel' => "Don't want to be our customer anymore? "
. "Here is how you can cancel your account:",
+
+ 'trialend-subject' => ":site: Your trial phase has ended",
+ 'trialend-intro' => "We hope you enjoyed the 30 days of free :site trial."
+ . " Your subscriptions become active after the first month of use and the fee is due after another month.",
+ 'trialend-kb' => "You can read about how to pay the subscription fee in this knowledge base article:",
+ 'trialend-body1' => "You can leave :site at any time, there is no contractual minimum period"
+ . " and your account will NOT be deleted automatically."
+ . " You can delete your account via the red [Delete account] button in your profile."
+ . " This will end your subscription and delete all relevant data.",
+ 'trialend-body2' => "THIS OPERATION IS IRREVERSIBLE!",
+ 'trialend-body3' => "When data is deleted it can not be recovered."
+ . " Please make sure that you have saved all data that you need before pressing the red button."
+ . " Do not hesitate to contact Support with any questions or concerns.",
];
diff --git a/src/resources/views/emails/html/trial_end.blade.php b/src/resources/views/emails/html/trial_end.blade.php
new file mode 100644
--- /dev/null
+++ b/src/resources/views/emails/html/trial_end.blade.php
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <p>{{ __('mail.header', ['name' => $username]) }}</p>
+ <p>{{ __('mail.trialend-intro', ['site' => $site]) }}</p>
+@if ($paymentUrl)
+ <p>{{ __('mail.trialend-kb', ['site' => $site]) }}</p>
+ <p><a href="{{ $paymentUrl }}">{{ $paymentUrl }}</a></p>
+@endif
+ <p>{{ __('mail.trialend-body1', ['site' => $site]) }}</p>
+ <p>{{ __('mail.trialend-body2', ['site' => $site]) }}</p>
+ <p>{{ __('mail.trialend-body3', ['site' => $site]) }}</p>
+ <p><a href="{{ $supportUrl }}">{{ $supportUrl }}</a></p>
+
+ <p>{{ __('mail.footer1') }}</p>
+ <p>{{ __('mail.footer2', ['site' => $site]) }}</p>
+ </body>
+</html>
diff --git a/src/resources/views/emails/plain/trial_end.blade.php b/src/resources/views/emails/plain/trial_end.blade.php
new file mode 100644
--- /dev/null
+++ b/src/resources/views/emails/plain/trial_end.blade.php
@@ -0,0 +1,19 @@
+{!! __('mail.header', ['name' => $username]) !!}
+
+{!! __('mail.trialend-intro', ['site' => $site]) !!}
+@if ($paymentUrl)
+
+{!! __('mail.trialend-kb', ['site' => $site]) !!} {!! $paymentUrl !!}
+@endif
+
+{!! __('mail.trialend-body1', ['site' => $site]) !!}
+
+{!! __('mail.trialend-body2', ['site' => $site]) !!}
+
+{!! __('mail.trialend-body3', ['site' => $site]) !!}
+
+{!! $supportUrl !!}
+
+--
+{!! __('mail.footer1') !!}
+{!! __('mail.footer2', ['site' => $site]) !!}
diff --git a/src/tests/Feature/Console/Wallet/TrialEndTest.php b/src/tests/Feature/Console/Wallet/TrialEndTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Console/Wallet/TrialEndTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Tests\Feature\Console\Wallet;
+
+use App\User;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Queue;
+use Tests\TestCase;
+
+class TrialEndTest extends TestCase
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->deleteTestUser('wallets-controller@kolabnow.com');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function tearDown(): void
+ {
+ $this->deleteTestUser('wallets-controller@kolabnow.com');
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test command run
+ */
+ public function testHandle(): void
+ {
+ Queue::fake();
+
+ $user = $this->getTestUser('wallets-controller@kolabnow.com', [
+ 'status' => User::STATUS_IMAP_READY | User::STATUS_LDAP_READY | User::STATUS_ACTIVE,
+ ]);
+ $wallet = $user->wallets()->first();
+
+ DB::table('users')->update(['created_at' => \now()->clone()->subMonthsNoOverflow(2)->subHours(1)]);
+
+ // Expect no wallets in after-trial state
+ Queue::fake();
+ $code = \Artisan::call("wallet:trial-end");
+ Queue::assertNothingPushed();
+
+ // Test an email sent
+ $user->created_at = \now()->clone()->subMonthNoOverflow();
+ $user->save();
+
+ Queue::fake();
+ $code = \Artisan::call("wallet:trial-end");
+ Queue::assertPushed(\App\Jobs\TrialEndEmail::class, 1);
+ Queue::assertPushed(\App\Jobs\TrialEndEmail::class, function ($job) use ($user) {
+ $job_user = TestCase::getObjectProperty($job, 'account');
+ return $job_user->id === $user->id;
+ });
+
+ $dt = $wallet->getSetting('trial_end_notice');
+ $this->assertMatchesRegularExpression('/^' . date('Y-m-d') . ' [0-9]{2}:[0-9]{2}:[0-9]{2}$/', $dt);
+
+ // Test no duplicate email sent for the same wallet
+ Queue::fake();
+ $code = \Artisan::call("wallet:trial-end");
+ Queue::assertNothingPushed();
+
+ // Test not imap ready user - no email sent
+ $wallet->setSetting('trial_end_notice', null);
+ $user->status = User::STATUS_NEW | User::STATUS_LDAP_READY | User::STATUS_ACTIVE;
+ $user->save();
+
+ Queue::fake();
+ $code = \Artisan::call("wallet:trial-end");
+ Queue::assertNothingPushed();
+
+ // Test deleted user - no email sent
+ $user->status = User::STATUS_NEW | User::STATUS_LDAP_READY | User::STATUS_ACTIVE | User::STATUS_IMAP_READY;
+ $user->save();
+ $user->delete();
+
+ Queue::fake();
+ $code = \Artisan::call("wallet:trial-end");
+ Queue::assertNothingPushed();
+
+ $this->assertNull($wallet->getSetting('trial_end_notice'));
+ }
+}
diff --git a/src/tests/Feature/Jobs/TrialEndEmailTest.php b/src/tests/Feature/Jobs/TrialEndEmailTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Feature/Jobs/TrialEndEmailTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Tests\Feature\Jobs;
+
+use App\Jobs\TrialEndEmail;
+use App\Mail\TrialEnd;
+use Illuminate\Support\Facades\Mail;
+use Tests\TestCase;
+
+class TrialEndEmailTest extends TestCase
+{
+ /**
+ * {@inheritDoc}
+ *
+ * @return void
+ */
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->deleteTestUser('PaymentEmail@UserAccount.com');
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return void
+ */
+ public function tearDown(): void
+ {
+ $this->deleteTestUser('PaymentEmail@UserAccount.com');
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test job handle
+ *
+ * @return void
+ */
+ public function testHandle()
+ {
+ $user = $this->getTestUser('PaymentEmail@UserAccount.com');
+ $user->setSetting('external_email', 'ext@email.tld');
+
+ Mail::fake();
+
+ // Assert that no jobs were pushed...
+ Mail::assertNothingSent();
+
+ $job = new TrialEndEmail($user);
+ $job->handle();
+
+ // Assert the email sending job was pushed once
+ Mail::assertSent(TrialEnd::class, 1);
+
+ // Assert the mail was sent to the user's email
+ Mail::assertSent(TrialEnd::class, function ($mail) {
+ return $mail->hasTo('paymentemail@useraccount.com') && !$mail->hasCc('ext@email.tld');
+ });
+ }
+}
diff --git a/src/tests/Unit/Mail/TrialEndTest.php b/src/tests/Unit/Mail/TrialEndTest.php
new file mode 100644
--- /dev/null
+++ b/src/tests/Unit/Mail/TrialEndTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Tests\Unit\Mail;
+
+use App\Mail\TrialEnd;
+use App\User;
+use Tests\TestCase;
+
+class TrialEndTest extends TestCase
+{
+ /**
+ * Test email content
+ */
+ public function testBuild(): void
+ {
+ $user = new User();
+
+ \config([
+ 'app.support_url' => 'https://kolab.org/support',
+ 'app.kb.payment_system' => 'https://kb.kolab.org/payment-system',
+ ]);
+
+ $mail = $this->renderMail(new TrialEnd($user));
+
+ $html = $mail['html'];
+ $plain = $mail['plain'];
+
+ $supportUrl = \config('app.support_url');
+ $supportLink = sprintf('<a href="%s">%s</a>', $supportUrl, $supportUrl);
+ $paymentUrl = \config('app.kb.payment_system');
+ $paymentLink = sprintf('<a href="%s">%s</a>', $paymentUrl, $paymentUrl);
+ $appName = \config('app.name');
+
+ $this->assertSame("$appName: Your trial phase has ended", $mail['subject']);
+
+ $this->assertStringStartsWith('<!DOCTYPE html>', $html);
+ $this->assertTrue(strpos($html, $user->name(true)) > 0);
+ $this->assertTrue(strpos($html, $supportLink) > 0);
+ $this->assertTrue(strpos($html, $paymentLink) > 0);
+ $this->assertTrue(strpos($html, "30 days of free $appName trial") > 0);
+ $this->assertTrue(strpos($html, "$appName Team") > 0);
+
+ $this->assertStringStartsWith('Dear ' . $user->name(true), $plain);
+ $this->assertTrue(strpos($plain, $supportUrl) > 0);
+ $this->assertTrue(strpos($plain, $paymentUrl) > 0);
+ $this->assertTrue(strpos($plain, "30 days of free $appName trial") > 0);
+ $this->assertTrue(strpos($plain, "$appName Team") > 0);
+ }
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 8:01 PM (4 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18830998
Default Alt Text
D3590.1775332865.diff (26 KB)
Attached To
Mode
D3590: "End of Trial" notification
Attached
Detach File
Event Timeline