diff --git a/.github/workflows/pull_request_unit_tests.yml b/.github/workflows/pull_request_unit_tests.yml
index 462317c3..9b21c15e 100644
--- a/.github/workflows/pull_request_unit_tests.yml
+++ b/.github/workflows/pull_request_unit_tests.yml
@@ -37,6 +37,8 @@ jobs:
PHP_VERSION: 8.3
OTEL_SDK_DISABLED: true
OTEL_SERVICE_ENABLED: false
+ MAIL_FROM_EMAIL: noreply@tipit.net
+ MAIL_FROM_NAME: noreply@tipit.net
services:
mysql:
image: mysql:8.0
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index ad2ede65..cfaf33c5 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -33,6 +33,8 @@ jobs:
PHP_VERSION: 8.3
OTEL_SDK_DISABLED: true
OTEL_SERVICE_ENABLED: false
+ MAIL_FROM_EMAIL: noreply@tipit.net
+ MAIL_FROM_NAME: noreply@tipit.net
services:
mysql:
image: mysql:8.0
diff --git a/resources/views/emails/auth/email_verification_request_success.blade.php b/resources/views/emails/auth/email_verification_request_success.blade.php
index 4edcc50f..aec5f807 100644
--- a/resources/views/emails/auth/email_verification_request_success.blade.php
+++ b/resources/views/emails/auth/email_verification_request_success.blade.php
@@ -1,33 +1,79 @@
@extends('emails.email_layout')
@section('content')
-
+
-
-
- Your {!! Config::get('app.app_name') !!} {!!$user_email!!} has been successfully verified.
- |
-
-
- @if(!empty($reset_password_link))
-
- Remember, if you need to set a password, you may do so here (link expires in {!! $reset_password_link_lifetime !!} minutes).
+ |
+
+
+
+ |
+ ✓
+ |
+
+ You're verified.
+ |
+
+
+
+ {{ $user_email }} is now your {!! Config::get('app.app_name') !!}.
+ |
+
+ @if(!empty($reset_password_link) || !$user_is_complete)
+
+ |
+
+ {{ !empty($reset_password_link) && !$user_is_complete ? 'Two quick things to finish setup:' : 'One quick thing to finish setup:' }}
+
+ |
+
+ @endif
+ @if(!empty($reset_password_link))
+
+
+
+
+
+ |
+ 1
+ |
+
+ Set your password
+ Link expires in {!! $reset_password_link_lifetime !!} minutes.
+ Set password →
+ |
+
+
+
+ |
+
+ @endif
+ @if(!$user_is_complete)
+
+
+
+
+
+ |
+ {{ !empty($reset_password_link) ? '2' : '1' }}
+ |
+
+ Complete your profile
+ Add your name, company, and country. Photo and bio optional.
+ Open profile →
+ |
+
+
+
+ |
+
+ @endif
+
+ |
+ Questions? {!! Config::get('app.help_email') !!}
|
- @endif
- @if(!$user_is_complete)
-
-
- You may enter your profile details here.
- |
-
- @endif
-
- |
-
- |
-
@stop
\ No newline at end of file
diff --git a/tests/unit/EmailVerificationSuccessViewTest.php b/tests/unit/EmailVerificationSuccessViewTest.php
new file mode 100644
index 00000000..89b3caec
--- /dev/null
+++ b/tests/unit/EmailVerificationSuccessViewTest.php
@@ -0,0 +1,95 @@
+createMock(User::class);
+ $user->method('getEmail')->willReturn($email);
+ $user->method('getFullName')->willReturn('Preview User');
+ $user->method('getFirstName')->willReturn($complete ? 'Preview' : null);
+ $user->method('getLastName')->willReturn($complete ? 'User' : null);
+ $user->method('getCompany')->willReturn($complete ? 'ACME Inc.' : null);
+ $user->method('getCountry')->willReturn($complete ? 'US' : null);
+ return $user;
+ }
+
+ public function testVerificationSuccessWithPasswordLinkAndIncompleteProfile(): void
+ {
+ $email = 'preview+verified@example.com';
+ $resetLink = 'https://id.fntech.com/reset/abc123deadbeef';
+
+ $mailable = new UserEmailVerificationSuccess($this->makeUser($email, false), $resetLink);
+
+ $mailable->assertHasSubject(
+ sprintf('[%1$s] %1$s Verified', Config::get('app.app_name'))
+ );
+ $mailable->assertTo($email);
+
+ $html = $mailable->render();
+
+ $this->assertStringContainsString("You're verified.", $html);
+ $this->assertStringContainsString($email, $html);
+ $this->assertStringContainsString(Config::get('app.app_name'), $html);
+ // Both steps present
+ $this->assertStringContainsString('Two quick things to finish setup', $html);
+ $this->assertStringContainsString('Set your password', $html);
+ $this->assertStringContainsString($resetLink, $html);
+ $this->assertStringContainsString('Complete your profile', $html);
+ $this->assertStringContainsString('Open profile', $html);
+ // Footer
+ $this->assertStringContainsString(Config::get('app.help_email'), $html);
+
+ }
+
+ public function testVerificationSuccessWithoutPasswordLinkAndCompleteProfile(): void
+ {
+ $email = 'preview+verified-complete@example.com';
+
+ $mailable = new UserEmailVerificationSuccess($this->makeUser($email, true), null);
+
+ $mailable->assertHasSubject(
+ sprintf('[%1$s] %1$s Verified', Config::get('app.app_name'))
+ );
+ $mailable->assertTo($email);
+
+ $html = $mailable->render();
+
+ $this->assertStringContainsString("You're verified.", $html);
+ $this->assertStringContainsString($email, $html);
+ // No steps — intro paragraph should be absent
+ $this->assertStringNotContainsString('Two quick things to finish setup', $html);
+ $this->assertStringNotContainsString('Set your password', $html);
+ $this->assertStringNotContainsString('Complete your profile', $html);
+ // Footer always present
+ $this->assertStringContainsString(Config::get('app.help_email'), $html);
+
+ }
+}