@@ -380,6 +380,40 @@ public function test_registration_does_not_create_private_organization_if_invite
380380 $ this ->assertSame ($ user ->organization ->id , $ organizations ->first ()->id );
381381 }
382382
383+ public function test_registration_joins_invited_organization_even_if_invitation_email_casing_differs (): void
384+ {
385+ // Arrange: invitation stored with a different casing than the registration email
386+ $ user = $ this ->createUserWithPermission ();
387+ OrganizationInvitation::factory ()
388+ ->forOrganization ($ user ->organization )
389+ ->role (Role::Employee)
390+ ->accepted ()
391+ ->create ([
392+ 'email ' => 'Invited.User@example.com ' ,
393+ ]);
394+
395+ // Act
396+ $ response = $ this ->post ('/register ' , [
397+ 'name ' => 'Invited User ' ,
398+ 'email ' => 'invited.user@example.com ' ,
399+ 'password ' => 'password ' ,
400+ 'password_confirmation ' => 'password ' ,
401+ 'terms ' => true ,
402+ ]);
403+
404+ // Assert: joined the inviting organization, no extra personal organization, invitation consumed
405+ $ this ->assertAuthenticated ();
406+ $ response ->assertRedirect (RouteServiceProvider::HOME );
407+ $ newUser = User::where ('email ' , 'invited.user@example.com ' )->first ();
408+ $ this ->assertNotNull ($ newUser );
409+ $ this ->assertDatabaseMissing (OrganizationInvitation::class, [
410+ 'email ' => 'Invited.User@example.com ' ,
411+ ]);
412+ $ organizations = $ newUser ->organizations ;
413+ $ this ->assertCount (1 , $ organizations );
414+ $ this ->assertSame ($ user ->organization ->id , $ organizations ->first ()->id );
415+ }
416+
383417 public function test_registration_logs_and_skips_accepted_invitation_with_invalid_role (): void
384418 {
385419 // Arrange
0 commit comments