Initial commit
This commit is contained in:
261
tests/Feature/MemberRegistrationTest.php
Normal file
261
tests/Feature/MemberRegistrationTest.php
Normal file
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Mail\MemberRegistrationWelcomeMail;
|
||||
use App\Models\Member;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MemberRegistrationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->artisan('db:seed', ['--class' => 'RoleSeeder']);
|
||||
}
|
||||
|
||||
public function test_public_registration_form_is_accessible(): void
|
||||
{
|
||||
$response = $this->get(route('register.member'));
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('Register');
|
||||
$response->assertSee('Full Name');
|
||||
$response->assertSee('Email');
|
||||
$response->assertSee('Password');
|
||||
}
|
||||
|
||||
public function test_can_register_with_valid_data(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'phone' => '0912345678',
|
||||
'address_line_1' => '123 Test St',
|
||||
'city' => 'Taipei',
|
||||
'postal_code' => '100',
|
||||
'emergency_contact_name' => 'Jane Doe',
|
||||
'emergency_contact_phone' => '0987654321',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('member.dashboard'));
|
||||
$response->assertSessionHas('status');
|
||||
|
||||
// Verify user created
|
||||
$this->assertDatabaseHas('users', [
|
||||
'email' => 'john@example.com',
|
||||
]);
|
||||
|
||||
// Verify member created
|
||||
$this->assertDatabaseHas('members', [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'phone' => '0912345678',
|
||||
'membership_status' => Member::STATUS_PENDING,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_and_member_records_created(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'phone' => '0912345678',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$user = User::where('email', 'john@example.com')->first();
|
||||
$member = Member::where('email', 'john@example.com')->first();
|
||||
|
||||
$this->assertNotNull($user);
|
||||
$this->assertNotNull($member);
|
||||
$this->assertEquals($user->id, $member->user_id);
|
||||
$this->assertTrue(Hash::check('Password123!', $user->password));
|
||||
}
|
||||
|
||||
public function test_user_is_auto_logged_in_after_registration(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$this->assertAuthenticated();
|
||||
|
||||
$user = User::where('email', 'john@example.com')->first();
|
||||
$this->assertEquals($user->id, auth()->id());
|
||||
}
|
||||
|
||||
public function test_welcome_email_is_sent(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
Mail::assertQueued(MemberRegistrationWelcomeMail::class, function ($mail) {
|
||||
return $mail->hasTo('john@example.com');
|
||||
});
|
||||
}
|
||||
|
||||
public function test_validation_fails_with_invalid_email(): void
|
||||
{
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'invalid-email',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('email');
|
||||
$this->assertDatabaseCount('users', 0);
|
||||
$this->assertDatabaseCount('members', 0);
|
||||
}
|
||||
|
||||
public function test_validation_fails_with_duplicate_email(): void
|
||||
{
|
||||
// Create existing user
|
||||
User::factory()->create(['email' => 'existing@example.com']);
|
||||
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'existing@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('email');
|
||||
}
|
||||
|
||||
public function test_validation_fails_with_duplicate_email_in_members(): void
|
||||
{
|
||||
// Create existing member without user
|
||||
Member::factory()->create(['email' => 'existing@example.com', 'user_id' => null]);
|
||||
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'existing@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('email');
|
||||
}
|
||||
|
||||
public function test_password_confirmation_required(): void
|
||||
{
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'DifferentPassword',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('password');
|
||||
$this->assertDatabaseCount('users', 0);
|
||||
}
|
||||
|
||||
public function test_terms_acceptance_required(): void
|
||||
{
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => false,
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('terms_accepted');
|
||||
$this->assertDatabaseCount('users', 0);
|
||||
}
|
||||
|
||||
public function test_registration_creates_audit_log(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('audit_logs', [
|
||||
'action' => 'member.self_registered',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_member_status_is_pending_after_registration(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
]);
|
||||
|
||||
$member = Member::where('email', 'john@example.com')->first();
|
||||
$this->assertEquals(Member::STATUS_PENDING, $member->membership_status);
|
||||
$this->assertEquals(Member::TYPE_REGULAR, $member->membership_type);
|
||||
}
|
||||
|
||||
public function test_required_fields_validation(): void
|
||||
{
|
||||
$response = $this->post(route('register.member.store'), []);
|
||||
|
||||
$response->assertSessionHasErrors(['full_name', 'email', 'password', 'terms_accepted']);
|
||||
}
|
||||
|
||||
public function test_optional_fields_can_be_null(): void
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$response = $this->post(route('register.member.store'), [
|
||||
'full_name' => 'John Doe',
|
||||
'email' => 'john@example.com',
|
||||
'password' => 'Password123!',
|
||||
'password_confirmation' => 'Password123!',
|
||||
'terms_accepted' => true,
|
||||
// Optional fields omitted
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('member.dashboard'));
|
||||
|
||||
$member = Member::where('email', 'john@example.com')->first();
|
||||
$this->assertNull($member->phone);
|
||||
$this->assertNull($member->address_line_1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user