From dc4bc979afb871c5f6a7c9d9677a06ed48b57128 Mon Sep 17 00:00:00 2001 From: oskar Date: Fri, 16 Jan 2026 21:46:00 +0100 Subject: [PATCH] Ensure tenant ID is properly set for patients, users, invitations, and patient-subject links in `InvitationService`; add corresponding unit tests. --- .../identity/service/InvitationService.kt | 7 +++++- .../identity/service/InvitationServiceTest.kt | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/back001/modules/identity/src/main/kotlin/com/mosenioring/identity/service/InvitationService.kt b/back001/modules/identity/src/main/kotlin/com/mosenioring/identity/service/InvitationService.kt index a7276de..55a37f6 100644 --- a/back001/modules/identity/src/main/kotlin/com/mosenioring/identity/service/InvitationService.kt +++ b/back001/modules/identity/src/main/kotlin/com/mosenioring/identity/service/InvitationService.kt @@ -40,13 +40,15 @@ class InvitationService( @Transactional @PreAuthorize("hasRole('ADMIN')") fun createPatientInvite(email: String, createdByAdmin: String?): InviteCreationResult { - requireNotNull(TenantContext.getTenantId()) { "Missing tenant" } + val tenantId = TenantContext.getTenantId() ?: throw IllegalArgumentException("Missing tenant") val patient = Patient(UUID.randomUUID().toString(), generatePatientPlaceholderName()) + patient.tenantId = tenantId val savedPatient = patientRepository.save(patient) keycloakProvisioningService.provisionUser(email, Invitation.ROLE_PATIENT)?.let { userId -> val user = User(userId, email, Invitation.ROLE_PATIENT, "INVITED") + user.tenantId = tenantId userRepository.save(user) } keycloakProvisioningService.sendSetPasswordEmail(email) @@ -64,6 +66,7 @@ class InvitationService( acceptedBy = null, createdByAdmin = createdByAdmin ) + invitation.tenantId = tenantId invitationRepository.save(invitation) return InviteCreationResult(token, invitation.expiresAt) } @@ -103,6 +106,7 @@ class InvitationService( throw IllegalArgumentException("Invitation email mismatch") } val newUser = User(authenticatedUserId, authenticatedEmail, invitation.role, "ACTIVE") + newUser.tenantId = TenantContext.getTenantId() ?: throw IllegalStateException("Missing tenant") userRepository.save(newUser) } @@ -140,6 +144,7 @@ class InvitationService( val tenantId = TenantContext.getTenantId() ?: throw IllegalStateException("Missing tenant") if (!subjectRepository.existsByTenantIdAndPatientIdAndUserId(tenantId, patientId, userId)) { val link = PatientSubject(UUID.randomUUID().toString(), patientId, userId) + link.tenantId = tenantId subjectRepository.save(link) } } diff --git a/back001/modules/identity/src/test/kotlin/com/mosenioring/identity/service/InvitationServiceTest.kt b/back001/modules/identity/src/test/kotlin/com/mosenioring/identity/service/InvitationServiceTest.kt index 254c6ea..2796adf 100644 --- a/back001/modules/identity/src/test/kotlin/com/mosenioring/identity/service/InvitationServiceTest.kt +++ b/back001/modules/identity/src/test/kotlin/com/mosenioring/identity/service/InvitationServiceTest.kt @@ -79,6 +79,28 @@ class InvitationServiceTest { assertEquals(Invitation.STATUS_ACCEPTED, invitation.status) assertNotNull(invitation.acceptedAt) assertEquals(user, invitation.acceptedBy) + org.mockito.kotlin.verify(subjectRepository).save(org.mockito.kotlin.check { + assertEquals("t1", it.tenantId) + }) + } + + @Test + fun `creates patient invite with tenantId`() { + val email = "new@example.com" + whenever(patientRepository.save(any())).thenAnswer { it.arguments[0] as Patient } + whenever(userRepository.save(any())).thenAnswer { it.arguments[0] as User } + whenever(invitationRepository.save(any())).thenAnswer { it.arguments[0] as Invitation } + + val result = service.createPatientInvite(email, "admin-1") + + assertNotNull(result.token) + org.mockito.kotlin.verify(patientRepository).save(org.mockito.kotlin.check { + assertEquals("t1", it.tenantId) + }) + org.mockito.kotlin.verify(invitationRepository).save(org.mockito.kotlin.check { + assertEquals("t1", it.tenantId) + assertEquals(email, it.email) + }) } @Test