So I added functionality to allow users to change only their own profile info but I'm having problem with adding that logic to test.
This is my Service and function where I check if user that is sending request is trying to update his own details.
public ApplicantDetailsResponseDTO updateByUserID(Integer id, ApplicantDetailsRequestDTO newApplicantDetails) {
ApplicantDetails applicantDetails = applicantDetailsRepository.findByUserId(id)
.orElseThrow(() -> new EntityNotFoundException("Details of applicant with ID " + id + " not found"));
if(!isAuthorizedForChange(applicantDetails.getUser().getUsername())) {
return null;
}
applicantDetails.setFirstname(newApplicantDetails.getFirstname());
applicantDetails.setLastname(newApplicantDetails.getLastname());
applicantDetails.setPhoneNumber(newApplicantDetails.getPhoneNumber());
ApplicantDetails updatedApplicantDetails = applicantDetailsRepository.save(applicantDetails);
return applicantDetailsMapper.mapToApplicantDetailsResponseDTO(updatedApplicantDetails);
}
public boolean isAuthorizedForChange(String username) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
UserDetails currentUser = (UserDetails) authentication.getPrincipal();
return Objects.equals(username, currentUser.getUsername());
}
This is my setup for test
@InjectMocks
private ApplicantDetailsService applicantDetailsService;
@Mock
private ApplicantDetailsRepository applicantDetailsRepository;
@Mock
private ApplicantDetailsMapper applicantDetailsMapper;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
And this is my try to mock isAuthorizedForChange and return true
Mockito.when(applicantDetailsService.isAuthorizedForChange("username")).thenReturn(true);
Problem is that function is still trying to run when I get to isAuthorizedForChange and get this error:
java.lang.NullPointerException: Cannot invoke "org.springframework.security.core.Authentication.getPrincipal()" because "authentication" is null
Is there a way just to return true when isAuthorizedForChange is called then I will create 2 test cases for when its true and when its false and test behavior.
I think your SecurityHolder doesn't have any context and auth. So we need to mock data for it.