package com.mydreamjob.bidirectionalmatch; import com.mydreamjob.auth.User; import com.mydreamjob.auth.UserRepository; import com.mydreamjob.security.UserRoleGuard; import com.mydreamjob.common.r01b.UserRoleGuardTestSupport; import com.mydreamjob.common.exception.BusinessException; import com.mydreamjob.common.exception.ErrorCode; import com.mydreamjob.company.Company; import com.mydreamjob.company.CompanyRepository; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.HashSet; import java.util.Optional; import java.util.Set; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class MatchRuleServiceTest { @BeforeEach void wireRoleGuard() { UserRoleGuardTestSupport.delegateToRealGuard(userRoleGuard, userRepository); } @Mock private CompanyMatchRuleRepository companyRuleRepository; @Mock private StudentMatchRuleRepository studentRuleRepository; @Mock private CompanyRepository companyRepository; @Mock private UserRepository userRepository; /** R01-B/B1:角色授权已委托给公共 guard;此处以委托桩保持既有断言语义。 */ @Mock private UserRoleGuard userRoleGuard; @InjectMocks private MatchRuleService matchRuleService; private static final Long COMPANY_USER_ID = 10L; private static final Long STUDENT_ID = 100L; private static final Long COMPANY_ID = 1L; private User userWithRole(Long id, User.Role role) { User u = User.builder().id(id).phone("1").role(role).build(); u.setRoles(new HashSet<>(Set.of(role))); return u; } // ── 企业 ────────────────────────────────────────────────── @Test void getCompanyRule_noRule_shouldReturnDefault60() { when(userRepository.findById(COMPANY_USER_ID)).thenReturn(Optional.of(userWithRole(COMPANY_USER_ID, User.Role.COMPANY))); when(companyRepository.findByOwnerUserId(COMPANY_USER_ID)) .thenReturn(Optional.of(Company.builder().id(COMPANY_ID).build())); when(companyRuleRepository.findByCompanyId(COMPANY_ID)).thenReturn(Optional.empty()); var view = matchRuleService.getCompanyRule(COMPANY_USER_ID); assertEquals(60, view.get("requiredCandidateScore")); assertEquals(COMPANY_ID, view.get("companyId")); } @Test void updateCompanyRule_shouldUpsert() { when(userRepository.findById(COMPANY_USER_ID)).thenReturn(Optional.of(userWithRole(COMPANY_USER_ID, User.Role.COMPANY))); when(companyRepository.findByOwnerUserId(COMPANY_USER_ID)) .thenReturn(Optional.of(Company.builder().id(COMPANY_ID).build())); when(companyRuleRepository.findByCompanyId(COMPANY_ID)).thenReturn(Optional.empty()); when(companyRuleRepository.save(any())).thenAnswer(inv -> inv.getArgument(0)); var view = matchRuleService.updateCompanyRule(COMPANY_USER_ID, 80); assertEquals(80, view.get("requiredCandidateScore")); verify(companyRuleRepository).save(argThat(r -> r.getCompanyId().equals(COMPANY_ID) && r.getRequiredCandidateScore() == 80)); } @Test void getCompanyRule_asStudent_shouldReturn403() { when(userRepository.findById(STUDENT_ID)).thenReturn(Optional.of(userWithRole(STUDENT_ID, User.Role.STUDENT))); BusinessException ex = assertThrows(BusinessException.class, () -> matchRuleService.getCompanyRule(STUDENT_ID)); assertEquals(ErrorCode.FORBIDDEN.getCode(), ex.getErrorCodeInt()); } @Test void getCompanyRule_noCompanyProfile_shouldReturn404() { when(userRepository.findById(COMPANY_USER_ID)).thenReturn(Optional.of(userWithRole(COMPANY_USER_ID, User.Role.COMPANY))); when(companyRepository.findByOwnerUserId(COMPANY_USER_ID)).thenReturn(Optional.empty()); BusinessException ex = assertThrows(BusinessException.class, () -> matchRuleService.getCompanyRule(COMPANY_USER_ID)); assertEquals(ErrorCode.COMPANY_NOT_FOUND.getCode(), ex.getErrorCodeInt()); } // ── 学生 ────────────────────────────────────────────────── @Test void getStudentRule_noRule_shouldReturnDefault60() { when(userRepository.findById(STUDENT_ID)).thenReturn(Optional.of(userWithRole(STUDENT_ID, User.Role.STUDENT))); when(studentRuleRepository.findByStudentUserId(STUDENT_ID)).thenReturn(Optional.empty()); var view = matchRuleService.getStudentRule(STUDENT_ID); assertEquals(60, view.get("requiredHrScore")); assertEquals(STUDENT_ID, view.get("studentUserId")); } @Test void updateStudentRule_shouldUpsert() { when(userRepository.findById(STUDENT_ID)).thenReturn(Optional.of(userWithRole(STUDENT_ID, User.Role.STUDENT))); when(studentRuleRepository.findByStudentUserId(STUDENT_ID)).thenReturn(Optional.empty()); when(studentRuleRepository.save(any())).thenAnswer(inv -> inv.getArgument(0)); var view = matchRuleService.updateStudentRule(STUDENT_ID, 75); assertEquals(75, view.get("requiredHrScore")); verify(studentRuleRepository).save(argThat(r -> r.getStudentUserId().equals(STUDENT_ID) && r.getRequiredHrScore() == 75)); } @Test void getStudentRule_asCompany_shouldReturn403() { when(userRepository.findById(COMPANY_USER_ID)).thenReturn(Optional.of(userWithRole(COMPANY_USER_ID, User.Role.COMPANY))); BusinessException ex = assertThrows(BusinessException.class, () -> matchRuleService.getStudentRule(COMPANY_USER_ID)); assertEquals(ErrorCode.FORBIDDEN.getCode(), ex.getErrorCodeInt()); } }