diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/NamespacePortalControllerTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/NamespacePortalControllerTest.java index ca620ab4..76775b1f 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/NamespacePortalControllerTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/controller/NamespacePortalControllerTest.java @@ -211,7 +211,9 @@ class NamespacePortalControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(0)) .andExpect(jsonPath("$.data.userId").value("user-2")) - .andExpect(jsonPath("$.data.role").value("ADMIN")); + .andExpect(jsonPath("$.data.role").value("ADMIN")) + .andExpect(jsonPath("$.data.displayName").value("Alice")) + .andExpect(jsonPath("$.data.email").value("alice@example.com")); } @Test @@ -250,7 +252,9 @@ class NamespacePortalControllerTest { .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(0)) .andExpect(jsonPath("$.data.userId").value("user-2")) - .andExpect(jsonPath("$.data.role").value("OWNER")); + .andExpect(jsonPath("$.data.role").value("OWNER")) + .andExpect(jsonPath("$.data.displayName").value("Alice")) + .andExpect(jsonPath("$.data.email").value("alice@example.com")); } @Test diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalCommandAppServiceTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalCommandAppServiceTest.java index 3da79373..719ad40d 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalCommandAppServiceTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalCommandAppServiceTest.java @@ -9,18 +9,24 @@ import static org.mockito.Mockito.when; import com.iflytek.skillhub.auth.rbac.PlatformPrincipal; import com.iflytek.skillhub.domain.namespace.Namespace; import com.iflytek.skillhub.domain.namespace.NamespaceGovernanceService; +import com.iflytek.skillhub.domain.namespace.NamespaceMember; import com.iflytek.skillhub.domain.namespace.NamespaceMemberService; import com.iflytek.skillhub.domain.namespace.NamespaceRepository; +import com.iflytek.skillhub.domain.namespace.NamespaceRole; import com.iflytek.skillhub.domain.namespace.NamespaceService; import com.iflytek.skillhub.domain.namespace.NamespaceStatus; import com.iflytek.skillhub.domain.namespace.NamespaceType; +import com.iflytek.skillhub.domain.user.UserAccount; import com.iflytek.skillhub.domain.user.UserAccountRepository; +import com.iflytek.skillhub.dto.MemberResponse; import com.iflytek.skillhub.dto.NamespaceLifecycleRequest; import com.iflytek.skillhub.dto.NamespaceRequest; +import com.iflytek.skillhub.dto.UpdateMemberRoleRequest; import com.iflytek.skillhub.exception.ForbiddenException; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; +import java.util.Optional; import java.util.Set; class NamespacePortalCommandAppServiceTest { @@ -74,4 +80,92 @@ class NamespacePortalCommandAppServiceTest { namespace.setType(NamespaceType.TEAM); return namespace; } + + @Test + void addMember_populatesDisplayNameAndEmail() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "user-2", NamespaceRole.ADMIN); + ReflectionTestUtils.setField(member, "id", 10L); + UserAccount user = new UserAccount("user-2", "Alice", "alice@example.com", null); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.addMember(1L, "user-2", NamespaceRole.ADMIN, "owner-1")) + .thenReturn(member); + when(userAccountRepository.findById("user-2")) + .thenReturn(Optional.of(user)); + + MemberResponse result = service.addMember("team-a", "user-2", NamespaceRole.ADMIN, "owner-1"); + + assertThat(result.userId()).isEqualTo("user-2"); + assertThat(result.displayName()).isEqualTo("Alice"); + assertThat(result.email()).isEqualTo("alice@example.com"); + assertThat(result.role()).isEqualTo(NamespaceRole.ADMIN); + } + + @Test + void addMember_withoutUserAccount_degradesGracefully() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "ghost", NamespaceRole.MEMBER); + ReflectionTestUtils.setField(member, "id", 20L); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.addMember(1L, "ghost", NamespaceRole.MEMBER, "owner-1")) + .thenReturn(member); + when(userAccountRepository.findById("ghost")) + .thenReturn(Optional.empty()); + + MemberResponse result = service.addMember("team-a", "ghost", NamespaceRole.MEMBER, "owner-1"); + + assertThat(result.userId()).isEqualTo("ghost"); + assertThat(result.displayName()).isNull(); + assertThat(result.email()).isNull(); + } + + @Test + void updateMemberRole_populatesDisplayNameAndEmail() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "user-2", NamespaceRole.OWNER); + ReflectionTestUtils.setField(member, "id", 10L); + UserAccount user = new UserAccount("user-2", "Alice", "alice@example.com", null); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.updateMemberRole(1L, "user-2", NamespaceRole.OWNER, "owner-1")) + .thenReturn(member); + when(userAccountRepository.findById("user-2")) + .thenReturn(Optional.of(user)); + + MemberResponse result = service.updateMemberRole( + "team-a", "user-2", + new UpdateMemberRoleRequest(NamespaceRole.OWNER), + "owner-1" + ); + + assertThat(result.userId()).isEqualTo("user-2"); + assertThat(result.displayName()).isEqualTo("Alice"); + assertThat(result.email()).isEqualTo("alice@example.com"); + assertThat(result.role()).isEqualTo(NamespaceRole.OWNER); + } + + @Test + void updateMemberRole_withoutUserAccount_degradesGracefully() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "ghost", NamespaceRole.MEMBER); + ReflectionTestUtils.setField(member, "id", 20L); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.updateMemberRole(1L, "ghost", NamespaceRole.ADMIN, "owner-1")) + .thenReturn(member); + when(userAccountRepository.findById("ghost")) + .thenReturn(Optional.empty()); + + MemberResponse result = service.updateMemberRole( + "team-a", "ghost", + new UpdateMemberRoleRequest(NamespaceRole.ADMIN), + "owner-1" + ); + + assertThat(result.userId()).isEqualTo("ghost"); + assertThat(result.displayName()).isNull(); + assertThat(result.email()).isNull(); + } } diff --git a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalQueryAppServiceTest.java b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalQueryAppServiceTest.java index bf5da955..7108fc40 100644 --- a/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalQueryAppServiceTest.java +++ b/server/skillhub-app/src/test/java/com/iflytek/skillhub/service/NamespacePortalQueryAppServiceTest.java @@ -1,20 +1,28 @@ package com.iflytek.skillhub.service; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.iflytek.skillhub.domain.namespace.Namespace; import com.iflytek.skillhub.domain.namespace.NamespaceAccessPolicy; +import com.iflytek.skillhub.domain.namespace.NamespaceMember; import com.iflytek.skillhub.domain.namespace.NamespaceMemberService; import com.iflytek.skillhub.domain.namespace.NamespaceRepository; import com.iflytek.skillhub.domain.namespace.NamespaceRole; import com.iflytek.skillhub.domain.namespace.NamespaceService; import com.iflytek.skillhub.domain.namespace.NamespaceStatus; import com.iflytek.skillhub.domain.namespace.NamespaceType; +import com.iflytek.skillhub.domain.user.UserAccount; import com.iflytek.skillhub.domain.user.UserAccountRepository; +import com.iflytek.skillhub.dto.MemberResponse; +import com.iflytek.skillhub.dto.PageResponse; import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; import org.springframework.test.util.ReflectionTestUtils; import java.util.List; @@ -70,4 +78,48 @@ class NamespacePortalQueryAppServiceTest { namespace.setType(NamespaceType.TEAM); return namespace; } + + @Test + void listMembers_withUserAccount_returnsDisplayNameAndEmail() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "user-2", NamespaceRole.ADMIN); + ReflectionTestUtils.setField(member, "id", 10L); + UserAccount user = new UserAccount("user-2", "Alice", "alice@example.com", null); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.listMembers(eq(1L), any(PageRequest.class))) + .thenReturn(new PageImpl<>(List.of(member), PageRequest.of(0, 20), 1)); + when(userAccountRepository.findByIdIn(List.of("user-2"))) + .thenReturn(List.of(user)); + + PageResponse result = service.listMembers("team-a", PageRequest.of(0, 20), "owner-1"); + + assertThat(result.items()).hasSize(1); + MemberResponse mr = result.items().get(0); + assertThat(mr.userId()).isEqualTo("user-2"); + assertThat(mr.displayName()).isEqualTo("Alice"); + assertThat(mr.email()).isEqualTo("alice@example.com"); + assertThat(mr.role()).isEqualTo(NamespaceRole.ADMIN); + } + + @Test + void listMembers_withoutUserAccount_returnsNullFields() { + Namespace ns = namespace(1L, "team-a"); + NamespaceMember member = new NamespaceMember(1L, "ghost-user", NamespaceRole.MEMBER); + ReflectionTestUtils.setField(member, "id", 20L); + + when(namespaceService.getNamespaceBySlug("team-a")).thenReturn(ns); + when(namespaceMemberService.listMembers(eq(1L), any(PageRequest.class))) + .thenReturn(new PageImpl<>(List.of(member), PageRequest.of(0, 20), 1)); + when(userAccountRepository.findByIdIn(List.of("ghost-user"))) + .thenReturn(List.of()); + + PageResponse result = service.listMembers("team-a", PageRequest.of(0, 20), "owner-1"); + + assertThat(result.items()).hasSize(1); + MemberResponse mr = result.items().get(0); + assertThat(mr.userId()).isEqualTo("ghost-user"); + assertThat(mr.displayName()).isNull(); + assertThat(mr.email()).isNull(); + } }