diff --git a/src/app/Jobs/WalletCheck.php b/src/app/Jobs/WalletCheck.php index 85e53e38..f7629bc3 100644 --- a/src/app/Jobs/WalletCheck.php +++ b/src/app/Jobs/WalletCheck.php @@ -1,397 +1,273 @@ wallet = $wallet; } /** * Execute the job. * * @return ?string Executed action (THRESHOLD_*) */ public function handle() { if ($this->wallet->balance >= 0) { return null; } $now = Carbon::now(); -/* - // Steps for old "first suspend then delete" approach - $steps = [ - // Send the initial reminder - self::THRESHOLD_INITIAL => 'initialReminder', - // Try to top-up the wallet before the second reminder - self::THRESHOLD_BEFORE_REMINDER => 'topUpWallet', - // Send the second reminder - self::THRESHOLD_REMINDER => 'secondReminder', - // Try to top-up the wallet before suspending the account - self::THRESHOLD_BEFORE_SUSPEND => 'topUpWallet', - // Suspend the account - self::THRESHOLD_SUSPEND => 'suspendAccount', - // Warn about the upcomming account deletion - self::THRESHOLD_BEFORE_DELETE => 'warnBeforeDelete', - // Delete the account - self::THRESHOLD_DELETE => 'deleteAccount', - ]; -*/ - // Steps for "demote instead of suspend+delete" approach + $steps = [ // Send the initial reminder self::THRESHOLD_INITIAL => 'initialReminderForDegrade', // Try to top-up the wallet before the second reminder self::THRESHOLD_BEFORE_REMINDER => 'topUpWallet', // Send the second reminder self::THRESHOLD_REMINDER => 'secondReminderForDegrade', // Try to top-up the wallet before the account degradation self::THRESHOLD_BEFORE_DEGRADE => 'topUpWallet', // Degrade the account self::THRESHOLD_DEGRADE => 'degradeAccount', ]; if ($this->wallet->owner && $this->wallet->owner->isDegraded()) { $this->degradedReminder(); return self::THRESHOLD_DEGRADE_REMINDER; } foreach (array_reverse($steps, true) as $type => $method) { if (self::threshold($this->wallet, $type) < $now) { $this->{$method}(); return $type; } } return null; } - /** - * Send the initial reminder (for the suspend+delete process) - */ - protected function initialReminder() - { - if ($this->wallet->getSetting('balance_warning_initial')) { - return; - } - - // TODO: Should we check if the account is already suspended? - - $this->sendMail(\App\Mail\NegativeBalance::class, false); - - $now = \Carbon\Carbon::now()->toDateTimeString(); - $this->wallet->setSetting('balance_warning_initial', $now); - } - /** * Send the initial reminder (for the process of degrading a account) */ protected function initialReminderForDegrade() { if ($this->wallet->getSetting('balance_warning_initial')) { return; } if (!$this->wallet->owner || $this->wallet->owner->isDegraded()) { return; } - $this->sendMail(\App\Mail\NegativeBalance::class, false); - - $now = \Carbon\Carbon::now()->toDateTimeString(); - $this->wallet->setSetting('balance_warning_initial', $now); - } - - /** - * Send the second reminder (for the suspend+delete process) - */ - protected function secondReminder() - { - if ($this->wallet->getSetting('balance_warning_reminder')) { - return; + if (!$this->wallet->owner->isSuspended()) { + $this->sendMail(\App\Mail\NegativeBalance::class, false); } - // TODO: Should we check if the account is already suspended? - - $this->sendMail(\App\Mail\NegativeBalanceReminder::class, false); - $now = \Carbon\Carbon::now()->toDateTimeString(); - $this->wallet->setSetting('balance_warning_reminder', $now); + $this->wallet->setSetting('balance_warning_initial', $now); } /** * Send the second reminder (for the process of degrading a account) */ protected function secondReminderForDegrade() { if ($this->wallet->getSetting('balance_warning_reminder')) { return; } if (!$this->wallet->owner || $this->wallet->owner->isDegraded()) { return; } - $this->sendMail(\App\Mail\NegativeBalanceReminderDegrade::class, true); + if (!$this->wallet->owner->isSuspended()) { + $this->sendMail(\App\Mail\NegativeBalanceReminderDegrade::class, true); + } $now = \Carbon\Carbon::now()->toDateTimeString(); $this->wallet->setSetting('balance_warning_reminder', $now); } /** - * Suspend the account (and send the warning) + * Degrade the account */ - protected function suspendAccount() + protected function degradeAccount() { - if ($this->wallet->getSetting('balance_warning_suspended')) { - return; - } - - // Sanity check, already deleted - if (!$this->wallet->owner) { + // The account may be already deleted, or degraded + if (!$this->wallet->owner || $this->wallet->owner->isDegraded()) { return; } - // Suspend the account - $this->wallet->owner->suspendAccount(); - - $this->sendMail(\App\Mail\NegativeBalanceSuspended::class, true); + $email = $this->wallet->owner->email; - $now = \Carbon\Carbon::now()->toDateTimeString(); - $this->wallet->setSetting('balance_warning_suspended', $now); - } + // The dirty work will be done by UserObserver + $this->wallet->owner->degrade(); - /** - * Send the last warning before delete - */ - protected function warnBeforeDelete() - { - if ($this->wallet->getSetting('balance_warning_before_delete')) { - return; - } + \Log::info( + sprintf( + "[WalletCheck] Account degraded %s (%s)", + $this->wallet->id, + $email + ) + ); - // Sanity check, already deleted - if (!$this->wallet->owner) { - return; + if (!$this->wallet->owner->isSuspended()) { + $this->sendMail(\App\Mail\NegativeBalanceDegraded::class, true); } - - $this->sendMail(\App\Mail\NegativeBalanceBeforeDelete::class, true); - - $now = \Carbon\Carbon::now()->toDateTimeString(); - $this->wallet->setSetting('balance_warning_before_delete', $now); } /** * Send the periodic reminder to the degraded account owners */ protected function degradedReminder() { // Sanity check if (!$this->wallet->owner || !$this->wallet->owner->isDegraded()) { return; } + if ($this->wallet->owner->isSuspended()) { + return; + } + $now = \Carbon\Carbon::now(); $last = $this->wallet->getSetting('degraded_last_reminder'); if ($last) { $last = new Carbon($last); $period = 14; if ($last->addDays($period) > $now) { return; } - $this->sendMail(\App\Mail\DegradedAccountReminder::class, true); + $this->sendMail(\App\Mail\DegradedAccountReminder::class, false); } $this->wallet->setSetting('degraded_last_reminder', $now->toDateTimeString()); } - /** - * Degrade the account - */ - protected function degradeAccount() - { - // The account may be already deleted, or degraded - if (!$this->wallet->owner || $this->wallet->owner->isDegraded()) { - return; - } - - $email = $this->wallet->owner->email; - - // The dirty work will be done by UserObserver - $this->wallet->owner->degrade(); - - \Log::info( - sprintf( - "[WalletCheck] Account degraded %s (%s)", - $this->wallet->id, - $email - ) - ); - - $this->sendMail(\App\Mail\NegativeBalanceDegraded::class, true); - } - - /** - * Delete the account - */ - protected function deleteAccount() - { - // TODO: This will not work when we actually allow multiple-wallets per account - // but in this case we anyway have to change the whole thing - // and calculate summarized balance from all wallets. - // The dirty work will be done by UserObserver - if ($this->wallet->owner) { - $email = $this->wallet->owner->email; - - $this->wallet->owner->delete(); - - \Log::info( - sprintf( - "[WalletCheck] Account deleted %s (%s)", - $this->wallet->id, - $email - ) - ); - } - } - /** * Send the email * * @param string $class Mailable class name * @param bool $with_external Use users's external email */ protected function sendMail($class, $with_external = false): void { // TODO: Send the email to all wallet controllers? $mail = new $class($this->wallet, $this->wallet->owner); list($to, $cc) = \App\Mail\Helper::userEmails($this->wallet->owner, $with_external); if (!empty($to) || !empty($cc)) { $params = [ 'to' => $to, 'cc' => $cc, 'add' => " for {$this->wallet->id}", ]; \App\Mail\Helper::sendMail($mail, $this->wallet->owner->tenant_id, $params); } } /** * Get the date-time for an action threshold. Calculated using * the date when a wallet balance turned negative. * * @param \App\Wallet $wallet A wallet * @param string $type Action type (one of self::THRESHOLD_*) * * @return \Carbon\Carbon The threshold date-time object */ public static function threshold(Wallet $wallet, string $type): ?Carbon { $negative_since = $wallet->getSetting('balance_negative_since'); // Migration scenario: balance<0, but no balance_negative_since set if (!$negative_since) { // 2h back from now, so first run can sent the initial notification $negative_since = Carbon::now()->subHours(2); $wallet->setSetting('balance_negative_since', $negative_since->toDateTimeString()); } else { $negative_since = new Carbon($negative_since); } // Initial notification // Give it an hour so the async recurring payment has a chance to be finished if ($type == self::THRESHOLD_INITIAL) { return $negative_since->addHours(1); } $thresholds = [ // A day before the second reminder self::THRESHOLD_BEFORE_REMINDER => 7 - 1, // Second notification self::THRESHOLD_REMINDER => 7, - - // A day before account suspension - self::THRESHOLD_BEFORE_SUSPEND => 14 + 7 - 1, - // Account suspension - self::THRESHOLD_SUSPEND => 14 + 7, - // Warning about the upcomming account deletion - self::THRESHOLD_BEFORE_DELETE => 21 + 14 + 7 - 3, - // Acount deletion - self::THRESHOLD_DELETE => 21 + 14 + 7, - // Last chance to top-up the wallet self::THRESHOLD_BEFORE_DEGRADE => 13, // Account degradation self::THRESHOLD_DEGRADE => 14, ]; if (!empty($thresholds[$type])) { return $negative_since->addDays($thresholds[$type]); } return null; } /** * Try to automatically top-up the wallet */ protected function topUpWallet(): void { PaymentsController::topUpWallet($this->wallet); } } diff --git a/src/app/Mail/NegativeBalanceBeforeDelete.php b/src/app/Mail/NegativeBalanceBeforeDelete.php deleted file mode 100644 index b05c0398..00000000 --- a/src/app/Mail/NegativeBalanceBeforeDelete.php +++ /dev/null @@ -1,84 +0,0 @@ -wallet = $wallet; - $this->user = $user; - } - - /** - * Build the message. - * - * @return $this - */ - public function build() - { - $threshold = WalletCheck::threshold($this->wallet, WalletCheck::THRESHOLD_DELETE); - $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); - $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url'); - - $subject = \trans('mail.negativebalancebeforedelete-subject', ['site' => $appName]); - - $this->view('emails.html.negative_balance_before_delete') - ->text('emails.plain.negative_balance_before_delete') - ->subject($subject) - ->with([ - 'site' => $appName, - 'subject' => $subject, - 'username' => $this->user->name(true), - 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id), - 'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id), - 'date' => $threshold->toDateString(), - ]); - - return $this; - } - - /** - * Render the mail template with fake data - * - * @param string $type Output format ('html' or 'text') - * - * @return string HTML or Plain Text output - */ - public static function fakeRender(string $type = 'html'): string - { - $wallet = new Wallet(); - $user = new User(); - - $mail = new self($wallet, $user); - - return Helper::render($mail, $type); - } -} diff --git a/src/app/Mail/NegativeBalanceReminder.php b/src/app/Mail/NegativeBalanceReminder.php deleted file mode 100644 index 211e7e21..00000000 --- a/src/app/Mail/NegativeBalanceReminder.php +++ /dev/null @@ -1,84 +0,0 @@ -wallet = $wallet; - $this->user = $user; - } - - /** - * Build the message. - * - * @return $this - */ - public function build() - { - $threshold = WalletCheck::threshold($this->wallet, WalletCheck::THRESHOLD_SUSPEND); - $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); - $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url'); - - $subject = \trans('mail.negativebalancereminder-subject', ['site' => $appName]); - - $this->view('emails.html.negative_balance_reminder') - ->text('emails.plain.negative_balance_reminder') - ->subject($subject) - ->with([ - 'site' => $appName, - 'subject' => $subject, - 'username' => $this->user->name(true), - 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id), - 'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id), - 'date' => $threshold->toDateString(), - ]); - - return $this; - } - - /** - * Render the mail template with fake data - * - * @param string $type Output format ('html' or 'text') - * - * @return string HTML or Plain Text output - */ - public static function fakeRender(string $type = 'html'): string - { - $wallet = new Wallet(); - $user = new User(); - - $mail = new self($wallet, $user); - - return Helper::render($mail, $type); - } -} diff --git a/src/app/Mail/NegativeBalanceSuspended.php b/src/app/Mail/NegativeBalanceSuspended.php deleted file mode 100644 index b83d5d17..00000000 --- a/src/app/Mail/NegativeBalanceSuspended.php +++ /dev/null @@ -1,84 +0,0 @@ -wallet = $wallet; - $this->user = $user; - } - - /** - * Build the message. - * - * @return $this - */ - public function build() - { - $threshold = WalletCheck::threshold($this->wallet, WalletCheck::THRESHOLD_DELETE); - $appName = Tenant::getConfig($this->user->tenant_id, 'app.name'); - $supportUrl = Tenant::getConfig($this->user->tenant_id, 'app.support_url'); - - $subject = \trans('mail.negativebalancesuspended-subject', ['site' => $appName]); - - $this->view('emails.html.negative_balance_suspended') - ->text('emails.plain.negative_balance_suspended') - ->subject($subject) - ->with([ - 'site' => $appName, - 'subject' => $subject, - 'username' => $this->user->name(true), - 'supportUrl' => Utils::serviceUrl($supportUrl, $this->user->tenant_id), - 'walletUrl' => Utils::serviceUrl('/wallet', $this->user->tenant_id), - 'date' => $threshold->toDateString(), - ]); - - return $this; - } - - /** - * Render the mail template with fake data - * - * @param string $type Output format ('html' or 'text') - * - * @return string HTML or Plain Text output - */ - public static function fakeRender(string $type = 'html'): string - { - $wallet = new Wallet(); - $user = new User(); - - $mail = new self($wallet, $user); - - return Helper::render($mail, $type); - } -} diff --git a/src/app/Mail/SuspendedDebtor.php b/src/app/Mail/SuspendedDebtor.php deleted file mode 100644 index 0840b935..00000000 --- a/src/app/Mail/SuspendedDebtor.php +++ /dev/null @@ -1,86 +0,0 @@ -account = $account; - } - - /** - * Build the message. - * - * @return $this - */ - public function build() - { - $appName = Tenant::getConfig($this->account->tenant_id, 'app.name'); - $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]); - - $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') - ->subject($subject) - ->with([ - 'site' => $appName, - 'subject' => $subject, - 'username' => $this->account->name(true), - 'cancelUrl' => $cancelUrl, - 'supportUrl' => Utils::serviceUrl($supportUrl, $this->account->tenant_id), - 'walletUrl' => Utils::serviceUrl('/wallet', $this->account->tenant_id), - 'moreInfoHtml' => $moreInfoHtml, - 'moreInfoText' => $moreInfoText, - 'days' => 14 // TODO: Configurable - ]); - - return $this; - } - - /** - * Render the mail template with fake data - * - * @param string $type Output format ('html' or 'text') - * - * @return string HTML or Plain Text output - */ - public static function fakeRender(string $type = 'html'): string - { - $user = new User(); - - $mail = new self($user); - - return Helper::render($mail, $type); - } -} diff --git a/src/resources/lang/en/mail.php b/src/resources/lang/en/mail.php index 6ee4b9eb..62a3fc80 100644 --- a/src/resources/lang/en/mail.php +++ b/src/resources/lang/en/mail.php @@ -1,123 +1,102 @@ "Dear :name,", 'footer1' => "Best regards,", 'footer2' => "Your :site Team", 'more-info-html' => "See here for more information.", 'more-info-text' => "See :href for more information.", 'degradedaccountreminder-subject' => ":site Reminder: Your account is free", 'degradedaccountreminder-body1' => "Thanks for sticking around, we remind you your account is a free " . "account and restricted to receiving email, and use of the web client and cockpit only.", 'degradedaccountreminder-body2' => "This leaves you with an ideal account to use for account registration with third parties " . "and password resets, notifications or even just subscriptions to newsletters and the like.", 'degradedaccountreminder-body3' => "To regain functionality such as sending email, calendars, address books, phone synchronization " . "and voice & video conferencing, log on to the cockpit and make sure you have a positive account balance.", 'degradedaccountreminder-body4' => "You can also delete your account there, making sure your data disappears from our systems.", 'degradedaccountreminder-body5' => "Thank you for your consideration!", 'negativebalance-subject' => ":site Payment Required", 'negativebalance-body' => "This is a notification to let you know that your :site account balance has run into the negative and requires your attention. " . "Consider setting up an automatic payment to avoid messages like this in the future.", 'negativebalance-body-ext' => "Settle up to keep your account running:", 'negativebalancereminder-subject' => ":site Payment Reminder", 'negativebalancereminder-body' => "It has probably skipped your attention that you are behind on paying for your :site account. " . "Consider setting up an automatic payment to avoid messages like this in the future.", 'negativebalancereminder-body-ext' => "Settle up to keep your account running:", - 'negativebalancereminder-body-warning' => "Please, be aware that your account will be suspended " - . "if your account balance is not settled by :date.", 'negativebalancereminderdegrade-body-warning' => "Please, be aware that your account will be degraded " . "if your account balance is not settled by :date.", 'negativebalancedegraded-subject' => ":site Account Degraded", 'negativebalancedegraded-body' => "Your :site account has been degraded for having a negative balance for too long. " . "Consider setting up an automatic payment to avoid messages like this in the future.", 'negativebalancedegraded-body-ext' => "Settle up now to undegrade your account:", - 'negativebalancesuspended-subject' => ":site Account Suspended", - 'negativebalancesuspended-body' => "Your :site account has been suspended for having a negative balance for too long. " - . "Consider setting up an automatic payment to avoid messages like this in the future.", - 'negativebalancesuspended-body-ext' => "Settle up now to unsuspend your account:", - 'negativebalancesuspended-body-warning' => "Please, be aware that your account and all its data will be deleted " - . "if your account balance is not settled by :date.", - - 'negativebalancebeforedelete-subject' => ":site Final Warning", - 'negativebalancebeforedelete-body' => "This is a final reminder to settle your :site account balance. " - . "Your account and all its data will be deleted if your account balance is not settled by :date.", - 'negativebalancebeforedelete-body-ext' => "Settle up now to keep your account:", - 'passwordreset-subject' => ":site Password Reset", 'passwordreset-body1' => "Someone recently asked to change your :site password.", 'passwordreset-body2' => "If this was you, use this verification code to complete the process:", 'passwordreset-body3' => "You can also click the link below:", 'passwordreset-body4' => "If you did not make such a request, you can either ignore this message or get in touch with us about this incident.", 'passwordexpiration-subject' => ":site password expires on :date", 'passwordexpiration-body' => "Your password will expire on :date. You can change it here:", 'paymentmandatedisabled-subject' => ":site Auto-payment Problem", 'paymentmandatedisabled-body' => "Your :site account balance is negative " . "and the configured amount for automatically topping up the balance does not cover " . "the costs of subscriptions consumed.", 'paymentmandatedisabled-body-ext' => "Charging you multiple times for the same amount in short succession " . "could lead to issues with the payment provider. " . "In order to not cause any problems, we suspended auto-payment for your account. " . "To resolve this issue, login to your account settings and adjust your auto-payment amount.", 'paymentfailure-subject' => ":site Payment Failed", 'paymentfailure-body' => "Something went wrong with auto-payment for your :site account.\n" . "We tried to charge you via your preferred payment method, but the charge did not go through.", 'paymentfailure-body-ext' => "In order to not cause any further issues, we suspended auto-payment for your account. " . "To resolve this issue, login to your account settings at", 'paymentfailure-body-rest' => "There you can pay manually for your account and " . "change your auto-payment settings.", 'paymentsuccess-subject' => ":site Payment Succeeded", 'paymentsuccess-body' => "The auto-payment for your :site account went through without issues. " . "You can check your new account balance and more details here:", 'support' => "Special circumstances? Something is wrong with a charge?\n" . ":site Support is here to help.", 'signupcode-subject' => ":site Registration", 'signupcode-body1' => "This is your verification code for the :site registration process:", 'signupcode-body2' => "You can also click the link below to continue the registration process:", 'signupinvitation-subject' => ":site Invitation", 'signupinvitation-header' => "Hi,", 'signupinvitation-body1' => "You have been invited to join :site. Click the link below to sign up.", 'signupinvitation-body2' => "", - 'suspendeddebtor-subject' => ":site Account Suspended", - 'suspendeddebtor-body' => "You have been behind on paying for your :site account " - . "for over :days days. Your account has been suspended.", - '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/lang/fr/mail.php b/src/resources/lang/fr/mail.php index bafbb111..59fe8da1 100644 --- a/src/resources/lang/fr/mail.php +++ b/src/resources/lang/fr/mail.php @@ -1,108 +1,87 @@ "Salut :name,", 'footer1' => "Meilleures salutations,", 'footer2' => "Votre :site Équipe", 'more-info-html' => "Cliquez ici pour plus d'information.", 'more-info-text' => "Cliquez :href pour plus d'information.", 'degradedaccountreminder-subject' => "Rappel du :site: Votre compte est gratuit", 'degradedaccountreminder-body1' => "Merci de ne pas quitter le site, nous vous rappelons que votre compte est gratuit." . " et limité à la réception d'emails, et à l'utilisation du client web et du cockpit uniquement.", 'degradedaccountreminder-body2' => "Vous disposez ainsi d'un compte idéal à employer pour l'enregistrement de comptes auprès de tiers" . " et les réinitialisations de mot de passe, les notifications ou même simplement les souscriptions aux newsletters et autres.", 'degradedaccountreminder-body3' => "Pour récupérer les fonctionnalités telles que l'envoi de e-mail, les calendriers, les carnets d'adresses et la synchronisation des téléphones" . " et les voix et vidéoconférences, connectez-vous au cockpit et assurez-vous que le solde de votre compte est positif.", 'degradedaccountreminder-body4' => "Vous pouvez également y supprimer votre compte, afin que vos données disparaissent de nos systèmes.", 'degradedaccountreminder-body5' => "Nous apprécions votre collaboration!", 'negativebalance-subject' => ":site Paiement Requis", 'negativebalance-body' => "C'est une notification pour vous informer que votre :site le solde du compte est en négatif et nécessite votre attention." . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.", 'negativebalance-body-ext' => "Régler votre compte pour le maintenir en fontion:", 'negativebalancereminder-subject' => ":site Rappel de Paiement", 'negativebalancereminder-body' => "Vous n'avez peut-être pas rendu compte que vous êtes en retard avec votre paiement pour :site compte." . " Veillez à mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.", 'negativebalancereminder-body-ext' => "Régler votre compte pour le maintenir en fontion:", - 'negativebalancereminder-body-warning' => "Soyez conscient que votre compte sera suspendu si le" - . " solde de votre compte n'est réglé avant le :date.", - - 'negativebalancesuspended-subject' => ":site Compte Suspendu", - 'negativebalancesuspended-body' => "Votre :site compte a été suspendu à la suite d'un solde négatif pendant trop longtemps." - . " Veillez nvisager de mettre en place un auto-paiement pour éviter de tel avertissement comme celui-ci dans le future.", - 'negativebalancesuspended-body-ext' => "Régler votre compte pour le maintenir en fontion:", - 'negativebalancesuspended-body-warning' => "Veuillez vous assurer que votre compte et toutes ses données seront supprimés" - . " si le solde de votre compte n'est pas réglé avant le :date.", - - 'negativebalancebeforedelete-subject' => ":site Dernier Avertissement", - 'negativebalancebeforedelete-body' => "Ceci-ci est le dernier rappel pour régler votre :site solde de compte." - . " votre compte et toutes ses données seront supprimés si le solde de votre compte nest pas régler avant le :date.", - 'negativebalancebeforedelete-body-ext' => "Régler votre compte immédiatement:", 'negativebalancereminderdegrade-body-warning' => "Veuillez noter que votre compte sera dégradé" . " si le solde de votre compte n'est pas réglé avant le :date.", 'negativebalancedegraded-subject' => ":site de Compte Dégradé", 'negativebalancedegraded-body' => "Votre compte :site a été dégradé pour avoir un solde négatif depuis trop longtemps." . " Envisagez de mettre en place un paiement automatique pour éviter des messages comme celui-ci à l'avenir.", 'negativebalancedegraded-body-ext' => "Réglez maintenant pour rétablir votre compte:", 'passwordreset-subject' => ":site Réinitialisation du mot de passe", 'passwordreset-body1' => "Quelqu'un a récemment demandé de changer votre :site mot de passe.", 'passwordreset-body2' => "Si vous êtes dans ce cas, veuillez utiliser ce code de vérification pour terminer le processus:", 'passwordreset-body3' => "Vous pourrez également cliquer sur le lien ci-dessous:", 'passwordreset-body4' => "si vous n'avez pas fait une telle demande, vous pouvez soit ignorer ce message, soit prendre contact avec nous au sujet de cet incident.", 'paymentmandatedisabled-subject' => ":site Problème d'auto-paiement", 'paymentmandatedisabled-body' => "Votre :site solde du compte est négatif" . " et le montant configuré pour le rechargement automatique du solde ne suffit pas" . " le coût des abonnements consommés.", 'paymentmandatedisabled-body-ext' => "En vous facturant plusieurs fois le même monant dans un court laps de temps" . " peut entraîner des problêmes avec le fournisseur du service de paiement." . " Pour éviter tout problème, nous avons suspendu l'auto-paiement pour votre compte." . " Pour resourdre le problème,veuillez vous connecter aux paramètres de votre compte et modifier le montant d'auto-paiement.", 'paymentfailure-subject' => ":site Paiement Echoué", 'paymentfailure-body' => "Un problème est survenu avec l'auto-paiement pour votre :site account.\n" . "Nous avons tenté de vous facturer via votre méthode de paiement choisie, mais le chargement n'a pas été effectué.", 'paymentfailure-body-ext' => "Pour éviter tout problème supplémentaire, nous avons suspendu l'auto-paiement sur votre compte." . " Pour resourdre le problème,veuillez vous connecter aux paramètres de votre compte au", 'paymentfailure-body-rest' => "Vous y trouverez la possibilité de payer manuellement votre compte et" . " de modifier vos paramètres d'auto-paiement.", 'paymentsuccess-subject' => ":site Paiement Effectué", 'paymentsuccess-body' => "L'auto-paiement pour votre :site le compte s'est exécuté sans problème. " . "Vous pouvez contrôler le solde de votre nouveau compte et obtenir plus de détails ici:", 'support' => "Cas particulier? Il y a un probléme avec une charge?\n" . ":site Le support reste à votre disposition.", 'signupcode-subject' => ":site Enregistrement", 'signupcode-body1' => "Voici votre code de vérification pour le :site registration process:", 'signupcode-body2' => "Vous pouvez également continuer avec le processus d'enregistrement en cliquant sur le lien ci-dessous:", 'signupinvitation-subject' => ":site Invitation", 'signupinvitation-header' => "Salut,", 'signupinvitation-body1' => "Vous êtes invité à joindre :site. Cliquez sur le lien ci-dessous pour vous inscrire.", 'signupinvitation-body2' => "", - 'suspendeddebtor-subject' => ":site Compte Suspendu", - 'suspendeddebtor-body' => "Vous êtes en retard avec le paiement de votre :site compte" - . " pour plus de :days jours. Votre compte est suspendu.", - 'suspendeddebtor-middle' => "Réglez immédiatement pour réactiver votre compte.", - 'suspendeddebtor-cancel' => "Vous ne souhaitez plus être notre client?" - . " Voici la démarche à suivre pour annuler votre compte:", - ]; diff --git a/src/resources/views/emails/html/negative_balance_before_delete.blade.php b/src/resources/views/emails/html/negative_balance_before_delete.blade.php deleted file mode 100644 index ee5b5476..00000000 --- a/src/resources/views/emails/html/negative_balance_before_delete.blade.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - -

{{ __('mail.header', ['name' => $username]) }}

- -

{{ __('mail.negativebalancebeforedelete-body', ['site' => $site, 'date' => $date]) }}

-

{{ __('mail.negativebalancebeforedelete-body-ext', ['site' => $site]) }}

-

{{ $walletUrl }}

- -@if ($supportUrl) -

{{ __('mail.support', ['site' => $site]) }}

-

{{ $supportUrl }}

-@endif - -

{{ __('mail.footer1') }}

-

{{ __('mail.footer2', ['site' => $site]) }}

- - diff --git a/src/resources/views/emails/html/negative_balance_reminder.blade.php b/src/resources/views/emails/html/negative_balance_reminder.blade.php deleted file mode 100644 index 876bd023..00000000 --- a/src/resources/views/emails/html/negative_balance_reminder.blade.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - -

{{ __('mail.header', ['name' => $username]) }}

- -

{{ __('mail.negativebalancereminder-body', ['site' => $site]) }}

-

{{ __('mail.negativebalancereminder-body-ext', ['site' => $site]) }}

-

{{ $walletUrl }}

-

{{ __('mail.negativebalancereminder-body-warning', ['site' => $site, 'date' => $date]) }}

- -@if ($supportUrl) -

{{ __('mail.support', ['site' => $site]) }}

-

{{ $supportUrl }}

-@endif - -

{{ __('mail.footer1') }}

-

{{ __('mail.footer2', ['site' => $site]) }}

- - diff --git a/src/resources/views/emails/html/negative_balance_suspended.blade.php b/src/resources/views/emails/html/negative_balance_suspended.blade.php deleted file mode 100644 index 6fde9c19..00000000 --- a/src/resources/views/emails/html/negative_balance_suspended.blade.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - -

{{ __('mail.header', ['name' => $username]) }}

- -

{{ __('mail.negativebalancesuspended-body', ['site' => $site]) }}

-

{{ __('mail.negativebalancesuspended-body-ext', ['site' => $site]) }}

-

{{ $walletUrl }}

-

{{ __('mail.negativebalancesuspended-body-warning', ['site' => $site, 'date' => $date]) }}

- -@if ($supportUrl) -

{{ __('mail.support', ['site' => $site]) }}

-

{{ $supportUrl }}

-@endif - -

{{ __('mail.footer1') }}

-

{{ __('mail.footer2', ['site' => $site]) }}

- - diff --git a/src/resources/views/emails/html/suspended_debtor.blade.php b/src/resources/views/emails/html/suspended_debtor.blade.php deleted file mode 100644 index 61453a0a..00000000 --- a/src/resources/views/emails/html/suspended_debtor.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - -

{{ __('mail.header', ['name' => $username]) }}

- -

{{ __('mail.suspendeddebtor-body', ['site' => $site, 'days' => $days]) }} {!! $moreInfoHtml !!}

-

{{ __('mail.suspendeddebtor-middle') }}

-

{{ $walletUrl }}

- -@if ($supportUrl) -

{{ __('mail.support', ['site' => $site]) }}

-

{{ $supportUrl }}

-@endif -@if ($cancelUrl) -

{{ __('mail.suspendeddebtor-cancel') }}

-

{{ $cancelUrl }}

-@endif - -

{{ __('mail.footer1') }}

-

{{ __('mail.footer2', ['site' => $site]) }}

- - diff --git a/src/resources/views/emails/plain/negative_balance_before_delete.blade.php b/src/resources/views/emails/plain/negative_balance_before_delete.blade.php deleted file mode 100644 index 29a76169..00000000 --- a/src/resources/views/emails/plain/negative_balance_before_delete.blade.php +++ /dev/null @@ -1,17 +0,0 @@ -{!! __('mail.header', ['name' => $username]) !!} - -{!! __('mail.negativebalancebeforedelete-body', ['site' => $site, 'date' => $date]) !!} - -{!! __('mail.negativebalancebeforedelete-body-ext', ['site' => $site]) !!} - -{!! $walletUrl !!} - -@if ($supportUrl) -{!! __('mail.support', ['site' => $site]) !!} - -{!! $supportUrl !!} -@endif - --- -{!! __('mail.footer1') !!} -{!! __('mail.footer2', ['site' => $site]) !!} diff --git a/src/resources/views/emails/plain/negative_balance_reminder.blade.php b/src/resources/views/emails/plain/negative_balance_reminder.blade.php deleted file mode 100644 index 6be4f048..00000000 --- a/src/resources/views/emails/plain/negative_balance_reminder.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -{!! __('mail.header', ['name' => $username]) !!} - -{!! __('mail.negativebalancereminder-body', ['site' => $site]) !!} - -{!! __('mail.negativebalancereminder-body-ext', ['site' => $site]) !!} - -{!! $walletUrl !!} - -{!! __('mail.negativebalancereminder-body-warning', ['site' => $site, 'date' => $date]) !!} - -@if ($supportUrl) -{!! __('mail.support', ['site' => $site]) !!} - -{!! $supportUrl !!} -@endif - --- -{!! __('mail.footer1') !!} -{!! __('mail.footer2', ['site' => $site]) !!} diff --git a/src/resources/views/emails/plain/negative_balance_suspended.blade.php b/src/resources/views/emails/plain/negative_balance_suspended.blade.php deleted file mode 100644 index e9049897..00000000 --- a/src/resources/views/emails/plain/negative_balance_suspended.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -{!! __('mail.header', ['name' => $username]) !!} - -{!! __('mail.negativebalancesuspended-body', ['site' => $site]) !!} - -{!! __('mail.negativebalancesuspended-body-ext', ['site' => $site]) !!} - -{!! $walletUrl !!} - -{!! __('mail.negativebalancesuspended-body-warning', ['site' => $site, 'date' => $date]) !!} - -@if ($supportUrl) -{!! __('mail.support', ['site' => $site]) !!} - -{!! $supportUrl !!} -@endif - --- -{!! __('mail.footer1') !!} -{!! __('mail.footer2', ['site' => $site]) !!} diff --git a/src/resources/views/emails/plain/suspended_debtor.blade.php b/src/resources/views/emails/plain/suspended_debtor.blade.php deleted file mode 100644 index c760dc75..00000000 --- a/src/resources/views/emails/plain/suspended_debtor.blade.php +++ /dev/null @@ -1,23 +0,0 @@ -{!! __('mail.header', ['name' => $username]) !!} - -{!! __('mail.suspendeddebtor-body', ['site' => $site, 'days' => $days]) !!} {!! $moreInfoText !!} - -{!! __('mail.suspendeddebtor-middle') !!} - -{!! $walletUrl !!} - -@if ($supportUrl) -{!! __('mail.support', ['site' => $site]) !!} - -{!! $supportUrl !!} -@endif -@if ($cancelUrl) - -{!! __('mail.suspendeddebtor-cancel') !!} - -{!! $cancelUrl !!} -@endif - --- -{!! __('mail.footer1') !!} -{!! __('mail.footer2', ['site' => $site]) !!} diff --git a/src/tests/Feature/Jobs/WalletCheckTest.php b/src/tests/Feature/Jobs/WalletCheckTest.php index 2822d81b..0c483e47 100644 --- a/src/tests/Feature/Jobs/WalletCheckTest.php +++ b/src/tests/Feature/Jobs/WalletCheckTest.php @@ -1,401 +1,305 @@ deleteTestUser('wallet-check@kolabnow.com'); } /** * {@inheritDoc} */ public function tearDown(): void { $this->deleteTestUser('wallet-check@kolabnow.com'); parent::tearDown(); } /** * Test job handle, initial negative-balance notification */ public function testHandleInitial(): void { Mail::fake(); $user = $this->prepareTestUser($wallet); $now = Carbon::now(); $wallet->balance = 0; $wallet->save(); $job = new WalletCheck($wallet); $job->handle(); Mail::assertNothingSent(); // Balance is negative now $wallet->balance = -100; $wallet->save(); $job = new WalletCheck($wallet); $job->handle(); Mail::assertNothingSent(); // Balance turned negative 2 hours ago, expect mail sent $wallet->setSetting('balance_negative_since', $now->subHours(2)->toDateTimeString()); $wallet->setSetting('balance_warning_initial', null); $job = new WalletCheck($wallet); $job->handle(); // Assert the mail was sent to the user's email, but not to his external email Mail::assertSent(\App\Mail\NegativeBalance::class, 1); Mail::assertSent(\App\Mail\NegativeBalance::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && !$mail->hasCc('external@test.com'); }); // Run the job again to make sure the notification is not sent again Mail::fake(); $job = new WalletCheck($wallet); $job->handle(); Mail::assertNothingSent(); // Test the migration scenario where a negative wallet has no balance_negative_since set yet Mail::fake(); $wallet->setSetting('balance_negative_since', null); $wallet->setSetting('balance_warning_initial', null); $job = new WalletCheck($wallet); $job->handle(); // Assert the mail was sent to the user's email, but not to his external email Mail::assertSent(\App\Mail\NegativeBalance::class, 1); Mail::assertSent(\App\Mail\NegativeBalance::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && !$mail->hasCc('external@test.com'); }); $wallet->refresh(); $today_regexp = '/' . Carbon::now()->toDateString() . ' [0-9]{2}:[0-9]{2}:[0-9]{2}/'; $this->assertMatchesRegularExpression($today_regexp, $wallet->getSetting('balance_negative_since')); $this->assertMatchesRegularExpression($today_regexp, $wallet->getSetting('balance_warning_initial')); + + // Test suspended user - no mail sent + Mail::fake(); + $wallet->owner->suspend(); + $wallet->setSetting('balance_warning_initial', null); + + $job = new WalletCheck($wallet); + $job->handle(); + + Mail::assertNothingSent(); } /** * Test job handle, top-up before reminder notification * * @depends testHandleInitial */ public function testHandleBeforeReminder(): void { Mail::fake(); $user = $this->prepareTestUser($wallet); $now = Carbon::now(); // Balance turned negative 7-1 days ago $wallet->setSetting('balance_negative_since', $now->subDays(7 - 1)->toDateTimeString()); $job = new WalletCheck($wallet); $res = $job->handle(); Mail::assertNothingSent(); // TODO: Test that it actually executed the topUpWallet() $this->assertSame(WalletCheck::THRESHOLD_BEFORE_REMINDER, $res); - $this->assertFalse($user->fresh()->isSuspended()); } /** * Test job handle, reminder notification * * @depends testHandleBeforeReminder */ public function testHandleReminder(): void { Mail::fake(); $user = $this->prepareTestUser($wallet); $now = Carbon::now(); // Balance turned negative 7+1 days ago, expect mail sent $wallet->setSetting('balance_negative_since', $now->subDays(7 + 1)->toDateTimeString()); $job = new WalletCheck($wallet); $job->handle(); // Assert the mail was sent to the user's email and to his external email Mail::assertSent(\App\Mail\NegativeBalanceReminderDegrade::class, 1); Mail::assertSent(\App\Mail\NegativeBalanceReminderDegrade::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasCc('external@test.com'); }); // Run the job again to make sure the notification is not sent again Mail::fake(); $job = new WalletCheck($wallet); $job->handle(); Mail::assertNothingSent(); - } - - /** - * Test job handle, top-up wallet before account suspending - * - * @depends testHandleReminder - */ -/* - public function testHandleBeforeSuspended(): void - { - Mail::fake(); - - $user = $this->prepareTestUser($wallet); - $now = Carbon::now(); - - // Balance turned negative 7+14-1 days ago - $days = 7 + 14 - 1; - $wallet->setSetting('balance_negative_since', $now->subDays($days)->toDateTimeString()); - - $job = new WalletCheck($wallet); - $res = $job->handle(); - - Mail::assertNothingSent(); - - // TODO: Test that it actually executed the topUpWallet() - $this->assertSame(WalletCheck::THRESHOLD_BEFORE_SUSPEND, $res); - $this->assertFalse($user->fresh()->isSuspended()); - } -*/ - /** - * Test job handle, account suspending - * - * @depends testHandleBeforeSuspended - */ -/* - public function testHandleSuspended(): void - { - Mail::fake(); - - $user = $this->prepareTestUser($wallet); - $now = Carbon::now(); - - // Balance turned negative 7+14+1 days ago, expect mail sent - $days = 7 + 14 + 1; - $wallet->setSetting('balance_negative_since', $now->subDays($days)->toDateTimeString()); - - $job = new WalletCheck($wallet); - $job->handle(); - - // Assert the mail was sent to the user's email, but not to his external email - Mail::assertSent(\App\Mail\NegativeBalanceSuspended::class, 1); - Mail::assertSent(\App\Mail\NegativeBalanceSuspended::class, function ($mail) use ($user) { - return $mail->hasTo($user->email) && $mail->hasCc('external@test.com'); - }); - - // Check that it has been suspended - $this->assertTrue($user->fresh()->isSuspended()); - - // TODO: Test that group account members/domain are also being suspended - - // Run the job again to make sure the notification is not sent again - Mail::fake(); - $job = new WalletCheck($wallet); - $job->handle(); - - Mail::assertNothingSent(); - } -*/ - /** - * Test job handle, final warning before delete - * - * @depends testHandleSuspended - */ -/* - public function testHandleBeforeDelete(): void - { - Mail::fake(); - - $user = $this->prepareTestUser($wallet); - $now = Carbon::now(); - - // Balance turned negative 7+14+21-3+1 days ago, expect mail sent - $days = 7 + 14 + 21 - 3 + 1; - $wallet->setSetting('balance_negative_since', $now->subDays($days)->toDateTimeString()); - - $job = new WalletCheck($wallet); - $job->handle(); - // Assert the mail was sent to the user's email, and his external email - Mail::assertSent(\App\Mail\NegativeBalanceBeforeDelete::class, 1); - Mail::assertSent(\App\Mail\NegativeBalanceBeforeDelete::class, function ($mail) use ($user) { - return $mail->hasTo($user->email) && $mail->hasCc('external@test.com'); - }); - - // Check that it has not been deleted yet - $this->assertFalse($user->fresh()->isDeleted()); - - // Run the job again to make sure the notification is not sent again + // Test suspended user - no mail sent Mail::fake(); - $job = new WalletCheck($wallet); - $job->handle(); - - Mail::assertNothingSent(); - } -*/ - /** - * Test job handle, account delete - * - * @depends testHandleBeforeDelete - */ -/* - public function testHandleDelete(): void - { - Mail::fake(); - - $user = $this->prepareTestUser($wallet); - $now = Carbon::now(); - - $this->assertFalse($user->isDeleted()); - $this->assertCount(7, $user->entitlements()->get()); - - // Balance turned negative 7+14+21+1 days ago, expect mail sent - $days = 7 + 14 + 21 + 1; - $wallet->setSetting('balance_negative_since', $now->subDays($days)->toDateTimeString()); + $wallet->owner->suspend(); + $wallet->setSetting('balance_warning_reminder', null); $job = new WalletCheck($wallet); $job->handle(); Mail::assertNothingSent(); - - // Check that it has not been deleted - $this->assertTrue($user->fresh()->trashed()); - $this->assertCount(0, $user->entitlements()->get()); - - // TODO: Test it deletes all members of the group account } -*/ /** * Test job handle, account degrade * * @depends testHandleReminder */ public function testHandleDegrade(): void { Mail::fake(); $user = $this->prepareTestUser($wallet); $now = Carbon::now(); $this->assertFalse($user->isDegraded()); // Balance turned negative 7+7+1 days ago, expect mail sent $days = 7 + 7 + 1; $wallet->setSetting('balance_negative_since', $now->subDays($days)->toDateTimeString()); $job = new WalletCheck($wallet); $job->handle(); // Assert the mail was sent to the user's email, and his external email Mail::assertSent(\App\Mail\NegativeBalanceDegraded::class, 1); Mail::assertSent(\App\Mail\NegativeBalanceDegraded::class, function ($mail) use ($user) { return $mail->hasTo($user->email) && $mail->hasCc('external@test.com'); }); // Check that it has been degraded $this->assertTrue($user->fresh()->isDegraded()); + + // Test suspended user - no mail sent + Mail::fake(); + $wallet->owner->suspend(); + $wallet->owner->undegrade(); + + $job = new WalletCheck($wallet); + $job->handle(); + + Mail::assertNothingSent(); } /** * Test job handle, periodic reminder to a degraded account * * @depends testHandleDegrade */ public function testHandleDegradeReminder(): void { Mail::fake(); $user = $this->prepareTestUser($wallet); $user->update(['status' => $user->status | User::STATUS_DEGRADED]); $now = Carbon::now(); $this->assertTrue($user->isDegraded()); // Test degraded_last_reminder not set $wallet->setSetting('degraded_last_reminder', null); $job = new WalletCheck($wallet); $res = $job->handle(); Mail::assertNothingSent(); $_last = Wallet::find($wallet->id)->getSetting('degraded_last_reminder'); $this->assertSame(Carbon::now()->toDateTimeString(), $_last); $this->assertSame(WalletCheck::THRESHOLD_DEGRADE_REMINDER, $res); // Test degraded_last_reminder set, but 14 days didn't pass yet $last = $now->copy()->subDays(10); $wallet->setSetting('degraded_last_reminder', $last->toDateTimeString()); $job = new WalletCheck($wallet); $res = $job->handle(); Mail::assertNothingSent(); $_last = $wallet->fresh()->getSetting('degraded_last_reminder'); $this->assertSame(WalletCheck::THRESHOLD_DEGRADE_REMINDER, $res); $this->assertSame($last->toDateTimeString(), $_last); // Test degraded_last_reminder set, and 14 days passed $wallet->setSetting('degraded_last_reminder', $now->copy()->subDays(14)->setSeconds(0)); $job = new WalletCheck($wallet); $res = $job->handle(); // Assert the mail was sent to the user's email, and his external email Mail::assertSent(\App\Mail\DegradedAccountReminder::class, 1); Mail::assertSent(\App\Mail\DegradedAccountReminder::class, function ($mail) use ($user) { - return $mail->hasTo($user->email) && $mail->hasCc('external@test.com'); + return $mail->hasTo($user->email) && !$mail->hasCc('external@test.com'); }); $_last = $wallet->fresh()->getSetting('degraded_last_reminder'); $this->assertSame(Carbon::now()->toDateTimeString(), $_last); $this->assertSame(WalletCheck::THRESHOLD_DEGRADE_REMINDER, $res); + + // Test suspended user - no mail sent + Mail::fake(); + $wallet->owner->suspend(); + $wallet->owner->undegrade(); + $wallet->setSetting('degraded_last_reminder', null); + + $job = new WalletCheck($wallet); + $job->handle(); + + Mail::assertNothingSent(); } /** * A helper to prepare a user for tests */ private function prepareTestUser(&$wallet) { $status = User::STATUS_ACTIVE | User::STATUS_LDAP_READY | User::STATUS_IMAP_READY; $user = $this->getTestUser('wallet-check@kolabnow.com', ['status' => $status]); $user->setSetting('external_email', 'external@test.com'); $wallet = $user->wallets()->first(); $package = \App\Package::withObjectTenantContext($user)->where('title', 'kolab')->first(); $user->assignPackage($package); $wallet->balance = -100; $wallet->save(); return $user; } } diff --git a/src/tests/Unit/Mail/NegativeBalanceBeforeDeleteTest.php b/src/tests/Unit/Mail/NegativeBalanceBeforeDeleteTest.php deleted file mode 100644 index 3385b0ab..00000000 --- a/src/tests/Unit/Mail/NegativeBalanceBeforeDeleteTest.php +++ /dev/null @@ -1,122 +0,0 @@ -getTestUser('ned@kolab.org'); - $wallet = $user->wallets->first(); - $wallet->balance = -100; - $wallet->save(); - - $threshold = WalletCheck::threshold($wallet, WalletCheck::THRESHOLD_DELETE); - - \config([ - 'app.support_url' => 'https://kolab.org/support', - ]); - - $mail = $this->renderMail(new NegativeBalanceBeforeDelete($wallet, $user)); - - $html = $mail['html']; - $plain = $mail['plain']; - - $walletUrl = \App\Utils::serviceUrl('/wallet'); - $walletLink = sprintf('%s', $walletUrl, $walletUrl); - $supportUrl = \config('app.support_url'); - $supportLink = sprintf('%s', $supportUrl, $supportUrl); - $appName = $user->tenant->title; - - $this->assertSame("$appName Final Warning", $mail['subject']); - - $this->assertStringStartsWith('', $html); - $this->assertTrue(strpos($html, $user->name(true)) > 0); - $this->assertTrue(strpos($html, $walletLink) > 0); - $this->assertTrue(strpos($html, $supportLink) > 0); - $this->assertTrue(strpos($html, "This is a final reminder to settle your $appName") > 0); - $this->assertTrue(strpos($html, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($html, "$appName Support") > 0); - $this->assertTrue(strpos($html, "$appName Team") > 0); - - $this->assertStringStartsWith('Dear ' . $user->name(true), $plain); - $this->assertTrue(strpos($plain, $walletUrl) > 0); - $this->assertTrue(strpos($plain, $supportUrl) > 0); - $this->assertTrue(strpos($plain, "This is a final reminder to settle your $appName") > 0); - $this->assertTrue(strpos($plain, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($plain, "$appName Support") > 0); - $this->assertTrue(strpos($plain, "$appName Team") > 0); - - // Test with user that is not the same tenant as in .env - $user = $this->getTestUser('user@sample-tenant.dev-local'); - $tenant = $user->tenant; - $wallet = $user->wallets->first(); - $wallet->balance = -100; - $wallet->save(); - - $threshold = WalletCheck::threshold($wallet, WalletCheck::THRESHOLD_DELETE); - - $tenant->setSettings([ - 'app.support_url' => 'https://test.org/support', - 'app.public_url' => 'https://test.org', - ]); - - $mail = $this->renderMail(new NegativeBalanceBeforeDelete($wallet, $user)); - - $html = $mail['html']; - $plain = $mail['plain']; - - $walletUrl = 'https://test.org/wallet'; - $walletLink = sprintf('%s', $walletUrl, $walletUrl); - $supportUrl = 'https://test.org/support'; - $supportLink = sprintf('%s', $supportUrl, $supportUrl); - - $this->assertSame("{$tenant->title} Final Warning", $mail['subject']); - - $this->assertStringStartsWith('', $html); - $this->assertTrue(strpos($html, $user->name(true)) > 0); - $this->assertTrue(strpos($html, $walletLink) > 0); - $this->assertTrue(strpos($html, $supportLink) > 0); - $this->assertTrue(strpos($html, "This is a final reminder to settle your {$tenant->title}") > 0); - $this->assertTrue(strpos($html, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($html, "{$tenant->title} Support") > 0); - $this->assertTrue(strpos($html, "{$tenant->title} Team") > 0); - - $this->assertStringStartsWith('Dear ' . $user->name(true), $plain); - $this->assertTrue(strpos($plain, $walletUrl) > 0); - $this->assertTrue(strpos($plain, $supportUrl) > 0); - $this->assertTrue(strpos($plain, "This is a final reminder to settle your {$tenant->title}") > 0); - $this->assertTrue(strpos($plain, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($plain, "{$tenant->title} Support") > 0); - $this->assertTrue(strpos($plain, "{$tenant->title} Team") > 0); - } -} diff --git a/src/tests/Unit/Mail/NegativeBalanceReminderTest.php b/src/tests/Unit/Mail/NegativeBalanceReminderTest.php deleted file mode 100644 index 9a669d77..00000000 --- a/src/tests/Unit/Mail/NegativeBalanceReminderTest.php +++ /dev/null @@ -1,59 +0,0 @@ -getTestUser('ned@kolab.org'); - $wallet = $user->wallets->first(); - $wallet->balance = -100; - $wallet->save(); - - $threshold = WalletCheck::threshold($wallet, WalletCheck::THRESHOLD_SUSPEND); - - \config([ - 'app.support_url' => 'https://kolab.org/support', - ]); - - $mail = $this->renderMail(new NegativeBalanceReminder($wallet, $user)); - - $html = $mail['html']; - $plain = $mail['plain']; - - $walletUrl = \App\Utils::serviceUrl('/wallet'); - $walletLink = sprintf('%s', $walletUrl, $walletUrl); - $supportUrl = \config('app.support_url'); - $supportLink = sprintf('%s', $supportUrl, $supportUrl); - $appName = $user->tenant->title; - - $this->assertSame("$appName Payment Reminder", $mail['subject']); - - $this->assertStringStartsWith('', $html); - $this->assertTrue(strpos($html, $user->name(true)) > 0); - $this->assertTrue(strpos($html, $walletLink) > 0); - $this->assertTrue(strpos($html, $supportLink) > 0); - $this->assertTrue(strpos($html, "you are behind on paying for your $appName account") > 0); - $this->assertTrue(strpos($html, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($html, "$appName Support") > 0); - $this->assertTrue(strpos($html, "$appName Team") > 0); - - $this->assertStringStartsWith('Dear ' . $user->name(true), $plain); - $this->assertTrue(strpos($plain, $walletUrl) > 0); - $this->assertTrue(strpos($plain, $supportUrl) > 0); - $this->assertTrue(strpos($plain, "you are behind on paying for your $appName account") > 0); - $this->assertTrue(strpos($plain, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($plain, "$appName Support") > 0); - $this->assertTrue(strpos($plain, "$appName Team") > 0); - } -} diff --git a/src/tests/Unit/Mail/NegativeBalanceSuspendedTest.php b/src/tests/Unit/Mail/NegativeBalanceSuspendedTest.php deleted file mode 100644 index 5a3cd110..00000000 --- a/src/tests/Unit/Mail/NegativeBalanceSuspendedTest.php +++ /dev/null @@ -1,59 +0,0 @@ -getTestUser('ned@kolab.org'); - $wallet = $user->wallets->first(); - $wallet->balance = -100; - $wallet->save(); - - $threshold = WalletCheck::threshold($wallet, WalletCheck::THRESHOLD_DELETE); - - \config([ - 'app.support_url' => 'https://kolab.org/support', - ]); - - $mail = $this->renderMail(new NegativeBalanceSuspended($wallet, $user)); - - $html = $mail['html']; - $plain = $mail['plain']; - - $walletUrl = \App\Utils::serviceUrl('/wallet'); - $walletLink = sprintf('%s', $walletUrl, $walletUrl); - $supportUrl = \config('app.support_url'); - $supportLink = sprintf('%s', $supportUrl, $supportUrl); - $appName = $user->tenant->title; - - $this->assertSame("$appName Account Suspended", $mail['subject']); - - $this->assertStringStartsWith('', $html); - $this->assertTrue(strpos($html, $user->name(true)) > 0); - $this->assertTrue(strpos($html, $walletLink) > 0); - $this->assertTrue(strpos($html, $supportLink) > 0); - $this->assertTrue(strpos($html, "Your $appName account has been suspended") > 0); - $this->assertTrue(strpos($html, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($html, "$appName Support") > 0); - $this->assertTrue(strpos($html, "$appName Team") > 0); - - $this->assertStringStartsWith('Dear ' . $user->name(true), $plain); - $this->assertTrue(strpos($plain, $walletUrl) > 0); - $this->assertTrue(strpos($plain, $supportUrl) > 0); - $this->assertTrue(strpos($plain, "Your $appName account has been suspended") > 0); - $this->assertTrue(strpos($plain, $threshold->toDateString()) > 0); - $this->assertTrue(strpos($plain, "$appName Support") > 0); - $this->assertTrue(strpos($plain, "$appName Team") > 0); - } -} diff --git a/src/tests/Unit/Mail/SuspendedDebtorTest.php b/src/tests/Unit/Mail/SuspendedDebtorTest.php deleted file mode 100644 index 320402cb..00000000 --- a/src/tests/Unit/Mail/SuspendedDebtorTest.php +++ /dev/null @@ -1,62 +0,0 @@ - 'https://kolab.org/support', - 'app.kb.account_suspended' => 'https://kb.kolab.org/account-suspended', - 'app.kb.account_delete' => 'https://kb.kolab.org/account-delete', - ]); - - $mail = $this->renderMail(new SuspendedDebtor($user)); - - $html = $mail['html']; - $plain = $mail['plain']; - - $walletUrl = \App\Utils::serviceUrl('/wallet'); - $walletLink = sprintf('%s', $walletUrl, $walletUrl); - $supportUrl = \config('app.support_url'); - $supportLink = sprintf('%s', $supportUrl, $supportUrl); - $deleteUrl = \config('app.kb.account_delete'); - $deleteLink = sprintf('%s', $deleteUrl, $deleteUrl); - $moreUrl = \config('app.kb.account_suspended'); - $moreLink = sprintf('here', $moreUrl); - $appName = \config('app.name'); - - $this->assertSame("$appName Account Suspended", $mail['subject']); - - $this->assertStringStartsWith('', $html); - $this->assertTrue(strpos($html, $user->name(true)) > 0); - $this->assertTrue(strpos($html, $walletLink) > 0); - $this->assertTrue(strpos($html, $supportLink) > 0); - $this->assertTrue(strpos($html, $deleteLink) > 0); - $this->assertTrue(strpos($html, "You have been behind on paying for your $appName account") > 0); - $this->assertTrue(strpos($html, "over 14 days") > 0); - $this->assertTrue(strpos($html, "See $moreLink for more information") > 0); - $this->assertTrue(strpos($html, "$appName Support") > 0); - $this->assertTrue(strpos($html, "$appName Team") > 0); - - $this->assertStringStartsWith('Dear ' . $user->name(true), $plain); - $this->assertTrue(strpos($plain, $walletUrl) > 0); - $this->assertTrue(strpos($plain, $supportUrl) > 0); - $this->assertTrue(strpos($plain, $deleteUrl) > 0); - $this->assertTrue(strpos($plain, "You have been behind on paying for your $appName account") > 0); - $this->assertTrue(strpos($plain, "over 14 days") > 0); - $this->assertTrue(strpos($plain, "See $moreUrl for more information") > 0); - $this->assertTrue(strpos($plain, "$appName Support") > 0); - $this->assertTrue(strpos($plain, "$appName Team") > 0); - } -}