I am in the process of creating tests for AdminClientService, which whould create users into Keycloak database. In the main processing it works as it should, but while creating tests i bumped into this exception:
java.lang.NullPointerException: RESTEASY004645: templateValues entry was null
at com.springboot.services.KeycloakAdminClientServiceTest.createKeycloakUserTest(KeycloakAdminClientServiceTest.java:80)
Here is the test, I am currently running:
#SpringBootTest
public class KeycloakAdminClientServiceTest {
#Value("${keycloak.auth-server-url}")
public String serverUrl;
#Value("${keycloak.realm}")
public String realm;
#Value("${keycloak.resource}")
public String clientId;
#Value("${keycloak.credentials.secret}")
public String clientSecret;
// #Mock
// KeycloakProvider kcProvider = Mockito.mock(KeycloakProvider.class);
// #InjectMocks
//
// #BeforeEach
// void setMockOutput() {
// //when(helloService.get()).thenReturn("Hello Mockito");
// Mockito.when(kcProvider.getInstance()).thenReturn(KeycloakBuilder.builder()
// .realm(realm)
// .serverUrl(serverUrl)
// .clientId(clientId)
// .clientSecret(clientSecret)
// .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
// .build());
// }
KeycloakProvider kcProvider;
KeycloakAdminClientService kcAdminClientService;
#BeforeEach
void createKeycloakProvider() {
kcProvider = new KeycloakProvider();
kcProvider.setServerUrl(serverUrl);
kcProvider.setRealm(realm);
kcProvider.setClientId(clientId);
kcProvider.setClientSecret(clientSecret);
kcAdminClientService = new KeycloakAdminClientService(kcProvider);
}
#Test
public void createKeycloakUserTest(){
Integer generatedInteger = (int) ((Math.random() * (9999999 - 1000000)) + 1000000);
String generatedString = generatedInteger.toString();
CreateUserRequest createUserRequest = new CreateUserRequest();
createUserRequest.setUsername("admin_client_username_" + generatedString);
createUserRequest.setPassword("admin_client_password");
createUserRequest.setEmail("admin_client_email_" + generatedString + "#gmail.com");
createUserRequest.setFirstname("admin_client_firstname_" + generatedString);
createUserRequest.setLastname("admin_client_lastname_" + generatedString);
kcAdminClientService.createKeycloakUser(createUserRequest);
UsersResource usersResource = kcProvider.getInstance()
.realm(kcAdminClientService.realm).users();
List<UserRepresentation> userRepresentation = usersResource
.search("admin_client_email_" + generatedString + "#gmail.com");
assertNotNull(userRepresentation);
assertEquals("admin_client_firstname_" + generatedString,
userRepresentation.get(0).getFirstName());
}
}
Here is the service:
#Service
public class KeycloakAdminClientService {
#Value("${keycloak.realm}")
public String realm;
private final KeycloakProvider kcProvider;
public KeycloakAdminClientService(KeycloakProvider keycloakProvider) {
this.kcProvider = keycloakProvider;
}
public Response createKeycloakUser(CreateUserRequest user) {
UsersResource usersResource = kcProvider.getInstance().realm(realm).users();
CredentialRepresentation credentialRepresentation = createPasswordCredentials(
user.getPassword());
UserRepresentation kcUser = new UserRepresentation();
kcUser.setUsername(user.getEmail());
kcUser.setCredentials(Collections.singletonList(credentialRepresentation));
kcUser.setFirstName(user.getFirstname());
kcUser.setLastName(user.getLastname());
kcUser.setEmail(user.getEmail());
kcUser.setEnabled(true);
kcUser.setEmailVerified(false);
Response response = usersResource.create(kcUser);
return response;
}
private static CredentialRepresentation createPasswordCredentials(String password) {
CredentialRepresentation passwordCredentials = new CredentialRepresentation();
passwordCredentials.setTemporary(false);
passwordCredentials.setType(CredentialRepresentation.PASSWORD);
passwordCredentials.setValue(password);
return passwordCredentials;
}
}
and the KeycloakProvider:
#Configuration
#Getter
#Setter
public class KeycloakProvider {
#Value("${keycloak.auth-server-url}")
public String serverUrl;
#Value("${keycloak.realm}")
public String realm;
#Value("${keycloak.resource}")
public String clientId;
#Value("${keycloak.credentials.secret}")
public String clientSecret;
private static Keycloak keycloak = null;
public KeycloakProvider() {
}
public Keycloak getInstance() {
if (keycloak == null) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.build();
}
return keycloak;
}
public KeycloakBuilder newKeycloakBuilderWithPasswordCredentials(
String username,
String password) {
return KeycloakBuilder.builder()
.realm(realm)
.serverUrl(serverUrl)
.clientId(clientId)
.clientSecret(clientSecret)
.username(username)
.password(password);
}
public JsonNode refreshToken(String refreshToken) throws UnirestException {
String url = serverUrl + "/realms/" + realm + "/protocol/openid-connect/token";
return Unirest.post(url)
.header("Content-Type", "application/x-www-form-urlencoded")
.field("client_id", clientId)
.field("client_secret", clientSecret)
.field("refresh_token", refreshToken)
.field("grant_type", "refresh_token")
.asJson().getBody();
}
}
I tried using Mockito for this problem, but realized it won't work, as I wanted it to.
Solved it myself, instead of that code above you just should write it like that, should've wrote #Autowired.
#Autowired
KeycloakProvider kcProvider;
#Autowired
KeycloakAdminClientService kcAdminClientService;
and it would solve all the problems)
Related
am trying to use S3TransferManager to upload file to s3. but my unit test fails due to the below error,
java.util.concurrent.CompletionException: software.amazon.awssdk.services.s3.model.S3Exception: Invalid response status from request
here's my code,
public class AwsTransferService {
private final S3TransferManager s3TransferManager;
private final AwsS3Config s3Config;
public AwsTransferService(AwsS3Config s3Config, AwsConfig awsConfig) {
this.s3Config = s3Config;
AwsBasicCredentials awsCredentials = create(awsConfig.getAccessKey(), awsConfig.getSecretKey());
this.s3TransferManager = S3TransferManager.builder()
.s3ClientConfiguration(builder -> builder.credentialsProvider(create(awsCredentials))
.region(s3Config.getRegion())
.minimumPartSizeInBytes(10 * MB)
.targetThroughputInGbps(20.0))
.build();
}
public AwsTransferService(S3TransferManager s3TransferManager, AwsS3Config s3Config) {
this.s3TransferManager = s3TransferManager;
this.s3Config = s3Config;
}
public void transferObject(#NonNull String bucketName, #NonNull String transferKey, #NonNull File file) {
validateS3Key(transferKey);
validatePath(file.toPath());
log.info("Transfering s3 object from :{} to :{}", file.getPath(), transferKey);
try {
Upload upload =
s3TransferManager.upload(b -> b.putObjectRequest(r -> r.bucket(bucketName).key(transferKey))
.source(file.toPath()));
CompletedUpload completedUpload = upload.completionFuture().join();
log.info("PutObjectResponse: " + completedUpload.response());
} catch (Exception e) {
e.printStackTrace();
}
}
and here is my unit test for the above code,
#RegisterExtension
public static final S3MockExtension S3_MOCK = builder()
.silent()
.withSecureConnection(false)
.build();
private S3ClientConfiguration s3ClientConfiguration;
private AwsTransferService service;
private AwsS3Service awsS3Service;
private S3TransferManager s3TransferManager;
private static S3Client s3Client;
#BeforeAll
public static void beforeAll() {
s3Client = S3_MOCK.createS3ClientV2();
}
#BeforeEach
public void beforeEach() throws IOException {
s3ClientConfiguration =mock(S3ClientConfiguration.class);
s3TransferManager = S3TransferManager.builder().s3ClientConfiguration(s3ClientConfiguration).build();
AwsS3Config s3Config = AwsS3Config.builder()
.region(Region.AP_SOUTHEAST_2)
.s3BucketName(S3Factory.VALID_S3_BUCKET)
.build();
awsS3Service = new AwsS3Service(s3Config, s3Client);
awsS3Service.createBucket(VALID_S3_BUCKET);
service = new AwsTransferService(s3TransferManager, s3Config);
}
#Test
public void transferObject_singleFile_ShouldUploadFiletoS3() throws IOException {
String transferKey = TRANSFER_KEY_UPLOAD;
String fileName = FILE_PATH + TRANSFER_FILE_NAME;
writeFile(fileName);
File transferFile = new File(fileName);
service.transferObject(VALID_S3_BUCKET, transferKey + TRANSFER_FILE_NAME, transferFile);
int expectedObjectsSize = 1;
Log.initLoggingToFile(Log.LogLevel.Error, "log.txt");
List<S3Object> matchedObjects = awsS3Service.listObjectsWithPrefix(transferKey + TRANSFER_FILE_NAME);
assertEquals(expectedObjectsSize, matchedObjects.size());
assertEquals(transferKey + TRANSFER_FILE_NAME, matchedObjects.get(0).key());
}
please let me know why the unit test fails with the above mentioned error?
also please let me know is there any other way to mock "s3ClientConfiguration"? in aws java sdk v2
I implement a custom security feature and I implement a login entry point :
#PostMapping("/login")
public ResponseEntity<UserRestResponseModel> userLogin(#RequestBody UserDetailsRequestModel userDetails) {
if(userDetails.getEmail().isEmpty() || userDetails.getPassword().isEmpty()) {
throw new UserServiceException(ErrorMessages.MISSING_REQUIRED_FIELD.getErrorMessage());
}
authenticate(userDetails.getEmail(), userDetails.getPassword());
UserRestResponseModel userRestResponseModel = new UserRestResponseModel();
ModelMapper modelMapper = new CustomMapper();
//modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
UserDto loggedInUser = userService.getUser(userDetails.getEmail());
if (loggedInUser == null)
throw new UserServiceException("Error !!");
if(loggedInUser.getIsAccountNonLocked() == Boolean.FALSE)
throw new UserServiceException("User account is locked");
userRestResponseModel = modelMapper.map(loggedInUser, UserRestResponseModel.class);
UserPrincipal userPrincipal = modelMapper.map(loggedInUser, UserPrincipal.class);
HttpHeaders jwtHeader = getJwtHeader(userPrincipal);
ResponseEntity<UserRestResponseModel> returnValue =
new ResponseEntity<>(userRestResponseModel, jwtHeader, HttpStatus.OK);
return returnValue;
}
private void authenticate(String userName, String password) {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userName, password));
}
private HttpHeaders getJwtHeader(UserPrincipal userPrincipal) {
HttpHeaders headers = new HttpHeaders();
String token = jwtTokenProvider.generateJwtToken(userPrincipal);
headers.add(SecurityConstants.TOKEN_PREFIX, token);
return headers;
}
I also implement my UserPrincipal class :
public class UserPrincipal implements UserDetails {
private static final long serialVersionUID = 7464059818443209139L;
private UserEntity userEntity;
private String userKeyId;
public UserPrincipal(){ }
public UserPrincipal(UserEntity userEntity) {
this.userEntity = userEntity;
this.userKeyId = userEntity.getUserKeyId();
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<>();
Collection<AuthorityEntity> authorityEntities = new HashSet<>();
// get user roles
Collection<RoleEntity> roles = userEntity.getRoles();
if (roles == null) {
return authorities; // null
}
// get user roles
roles.forEach((role) ->{
authorities.add(new SimpleGrantedAuthority(role.getName()));
authorityEntities.addAll(role.getAuthorities());
});
// get user authorities
authorityEntities.forEach(authorityEntity ->
authorities.add(
new SimpleGrantedAuthority(authorityEntity.getName())
)
);
return authorities;
}
#Override
public String getPassword() {
return this.userEntity.getEncryptedPassword();
}
#Override
public String getUsername() {
return this.userEntity.getEmail();
}
#Override
public boolean isAccountNonExpired() {
return this.userEntity.getIsAccountNonExpired();
}
I also have a JwtTokenProvider class that handle token.
#Component
public class JwtTokenProvider {
public String generateJwtToken(UserPrincipal userPrincipal) {
String[] claims = getClaimsFromUser(userPrincipal);
return JWT.create()
.withIssuer(SecurityConstants.TOKEN_ISSUER)
.withAudience(SecurityConstants.TOKEN_AUDIENCE)
.withIssuedAt(new Date())
.withSubject(userPrincipal.getUsername())
.withArrayClaim(SecurityConstants.AUTHORITIES, claims)
.withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.sign(Algorithm.HMAC512(SecurityConstants.getTokenSecret().getBytes()));
}
public List<GrantedAuthority> getAuthorities(String token) {
String[] claims = getClaimsFromToken(token);
return stream(claims).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
}
public Authentication getAuthentication(String userName,
List<GrantedAuthority> authorities,
HttpServletRequest request) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userName, null, authorities);
usernamePasswordAuthenticationToken.setDetails(
new WebAuthenticationDetailsSource().buildDetails(request));
return usernamePasswordAuthenticationToken;
}
public boolean isTokenValid(String userName, String token) {
JWTVerifier verifier = getJWTVerifier();
return StringUtils.isNotEmpty(userName) && !isTokenExpired(verifier, token);
}
public String getSubject(String token) {
JWTVerifier jwtVerifier = getJWTVerifier();
return jwtVerifier.verify(token).getSubject();
}
private boolean isTokenExpired(JWTVerifier verifier, String token) {
Date expirationDate = verifier.verify(token).getExpiresAt();
return expirationDate.before(new Date());
}
private String[] getClaimsFromToken(String token) {
JWTVerifier verifier = getJWTVerifier();
return verifier.verify(token).getClaim("Authorities").asArray(String.class);
}
private JWTVerifier getJWTVerifier() {
JWTVerifier verifier;
try {
Algorithm algorithm = Algorithm.HMAC512(SecurityConstants.getTokenSecret());
verifier = JWT.require(algorithm).withIssuer(SecurityConstants.TOKEN_ISSUER).build();
} catch (JWTVerificationException e) {
throw new JWTVerificationException(SecurityConstants.TOKEN_CANNOT_BE_VERIFIED);
}
return verifier;
}
private String[] getClaimsFromUser(UserPrincipal userPrincipal) {
List<String> authorities = new ArrayList<>();
for(GrantedAuthority grantedAuthority: userPrincipal.getAuthorities()) {
authorities.add(grantedAuthority.getAuthority());
}
return authorities.toArray(new String[0]);
}
}
Everything works fine except that I have 2 issues :
If i don't have a no argument constructor in my UserPrincipal class, model mapper returns an error...
"message": "An error occurred while processing the request ModelMapper mapping errors: Failed to instantiate instance of destination UserPrincipal. Ensure that UserPrincipal has a non-private no-argument constructor. 1 error".
And if i do add a no argument constructor, I have a null pointer exception (userPrincipal is null) with a nice 500 error. it drives me crazy.
My issue is around this place in my code:
UserDto loggedInUser = userService.getUser(userDetails.getEmail());
...
userRestResponseModel = modelMapper.map(loggedInUser, UserRestResponseModel.class);
UserPrincipal userPrincipal = modelMapper.map(loggedInUser, UserPrincipal.class);
HttpHeaders jwtHeader = getJwtHeader(userPrincipal);
I am trying to write a test case for a method which calls a service with client Id and client Secret.But i am getting nullpointer exception from the Junit.I am not able to pass the clientId and client secret using Junit below is my code
#Service
public class ourClientServiceImpl implements ourClientService {
private static final Logger ourClientServiceLogger = LoggerFactory.getLogger(ourClientServiceImpl.class);
#Value("${service-description.our-service.base-url}")
private String ourServiceBaseUrl;
#Value("${service-description.posting-service.subscription-key}")
private String subscriptionKey;
#Autowired
#Qualifier("clientRestTemplate")
private RestTemplate clientRestTemplate;
#Value("${token.scope}")
private String scope;
#Value("${token.grantType}")
private String grantType;
#Autowired
private PingfedConfig config;
/**
* Method to fetch our Name based on our Number
*
* #param ourNumber ourNumber
* #return our Details
*/
#Override
public ourResponse fetchDetailsClient(String ourNumber) {
ourClientServiceLogger.info("Fetching our name for our number::{}", ourNumber);
final String resourceUrl = ourServiceBaseUrl + "/our?our-number=" + ourNumber;
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(resourceUrl);
UriComponents uriComponents = builder.build().encode();
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + getJWTAuthenticationToken());
ResponseEntity<ourResponse> ourServiceResponseResponse = clientRestTemplate.exchange(uriComponents.toUri(), HttpMethod.GET, new HttpEntity<>("parameters", headers),
new ParameterizedTypeReference<ourResponse>() {
});
return ourServiceResponseResponse.getBody();
}
private String getJWTAuthenticationToken() {
ourClientServiceLogger.info("Getting the JWT token");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBasicAuth(config.getClientId(), config.getClientSecret());
HttpEntity formEntity = new HttpEntity<>(null, headers);
ResponseEntity<JWTTokenResponse> jwtToken = clientRestTemplate.exchange(config.getTokenUrl() + "?grant_type=client_credentials&Scope=openid", HttpMethod.POST, formEntity, JWTTokenResponse.class);
if (jwtToken != null && jwtToken.getBody() != null) {
return jwtToken.getBody().getAccessToken();
} else {
return null;
}
}
}
The jUnit class
#RunWith(MockitoJUnitRunner.class)
public class OurClientServiceTest {
private final OurResponse expectedOurResponse = OurResponse.builder().eourNumber("15253").ourName("New").build();
private static final String jwtMockToken = "Bearer vgftyuuuuuuuuuuuuuuuuuuuu";
private final JWTTokenResponse jwtTokenResponse = JWTTokenResponse.builder().tokenType("Bearer").expiresIn("Now").extExpiresIn("Now").expiresOn("Now").notBefore("Now").resource("Now").accessToken(jwtMockToken).build();
#InjectMocks
private OurClientServiceImpl ourClientService;
#Mock
#Qualifier("clientRestTemplate")
private RestTemplate clientRestTemplate;
#Autowired
private PingfedConfig config;
OurResponse ourResponse = OurResponse.builder().ourNumber("15253").build();
ResponseEntity<OurResponse> ourResponseEntity = new ResponseEntity<>(ourResponse, HttpStatus.OK);
ResponseEntity<JWTTokenResponse> jwtTokenResponseEntity = new ResponseEntity<>(jwtTokenResponse, HttpStatus.OK);
#Before
public void setJwtTokenResponseEntity() {
when(clientRestTemplate.exchange(
anyString(),
any(HttpMethod.class),
any(HttpEntity.class),
eq(JWTTokenResponse.class))).thenReturn(jwtTokenResponseEntity);
}
#Test
public void testFetchOurDetailsClient() {
when(clientRestTemplate.exchange(
anyString(),
any(HttpMethod.class),
any(HttpEntity.class),
eq(VendorResponse.class))).thenReturn(ourResponseEntity);
OurResponse actualResponse = ourClientService.fetchVendorDetailsClient("15253");
Assert.assertEquals(expectedOurResponse.getVendorNumber(), actualOurResponse.getOurNumber());
Assert.assertEquals(expectedOurResponse.getVendorName(), actualOurResponse.getOurName());
}
}
Please let me know where i am doing wrong .Thanks in advance
I am trying to create a Mock of my controller to update data inside user. From the code I am trying to update only the email, password, and age. Is this how we should do the mock? Because I'm still really new with this Mockito and Junit
Controller Mock
#Test
public void testUpdateUserController() throws Exception{
String username = "User";
String email = "user#email.com";
String password = "password123";
int age = 90;
Mockito.when(userService.updateUser(username,email,password,age)).then(invocationOnMock -> {
User user = new User();
user.setUsername("User");
user.setEmail("user#user.com");
user.setPassword("123456");
user.setAge(12);
user.setAddress("11111");
user.setIsActive(true);
return Optional.of(user);
});
mockMvc.perform(MockMvcRequestBuilders.put(BASE_URL + "/users/{username}",username)
.contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(userService, Mockito.times(1)).updateUser(userCaptor.capture(),emailCaptor.capture(),passwordCaptor.capture(),ageCaptor.capture());
Assert.assertEquals("User", userCaptor.getValue());
Assert.assertEquals("user#email.com", emailCaptor.getValue());
Assert.assertEquals("password123", passwordCaptor.getValue());
Assert.assertEquals("90", ageCaptor.getValue());
Assert.assertEquals("11111", addressCaptor.getValue());
}
UserServiceImpl
#Override
public boolean updateUser(String username, String email, String password, Integer age) {
Optional<User> userList = userRepository.findByUsernameAndIsActiveTrue(username);
if (userList.isPresent()) {
User user = userList.get();
user.setEmail(email);
user.setPassword(password);
user.setAge(age);
userRepository.save(user);
return true;
} else {
return false;
}
}
Here is one of my code samples for MVC Mocks
#RunWith(PowerMockRunner.class)
public class TrainingControllerTest {
#Mock
private TrainingService trainingService;
#Mock
private FileStorageService fileStorageService;
#InjectMocks
private TrainingController controller = new TrainingController();
private MockMvc mockMvc;
#Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(new ExceptionController())
.build();
}
#Test
public void testCreateHappyPath() throws Exception {
Training training = new Training();
Optional<Training> result = Optional.of(training);
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.createTraining(any(Training.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String trainingPayloadJSON = mapper.writerFor(Training.class).writeValueAsString(training);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.post(TestConstants.POST_TRAINING_URI)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(trainingPayloadJSON)
)
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
#Test
public void testPutHappyPath() throws Exception {
Training training = new Training();
Optional<Training> result = Optional.of(training);
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.update(any(Training.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String trainingPayloadJSON = mapper.writerFor(Training.class).writeValueAsString(training);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.put(TestConstants.GET_PUT_DELETE_TRAINING_URI, TestConstants.ID)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(trainingPayloadJSON)
)
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
#Test
public void testAddAttendeesHappyPath() throws Exception {
Attendees attendees = new Attendees();
Optional<Training> result = Optional.of(new Training());
TrainingExt ext = result
.map(TrainingExt::of)
.get();
when(trainingService.registerTrainingAttendees(any(Attendees.class))).thenReturn(result);
ObjectMapper mapper = new ObjectMapper();
String attendeesPayloadJSON = mapper.writerFor(Attendees.class).writeValueAsString(attendees);
String trainingExtJSON = mapper.writerFor(TrainingExt.class).writeValueAsString(ext);
mockMvc.perform(MockMvcRequestBuilders.post(TestConstants.ADD_ATTENDEES_URI)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(attendeesPayloadJSON)
)
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(content().json(trainingExtJSON));
}
}
I have a Rest API
The class code is :
#SpringBootTest
#RunWith(SpringRunner.class)
public class FetchCoreVersionsListIT {
#MockBean
private RestTemplateBuilder restTemplateBuilder;
#MockBean
private RestTemplate restTemplate;
private VersionsService versionsService;
#Autowired
private FetchCoreVersionsList fetchCoreVersionsList;
private VersionList versionList;
private ArtifactoryFolderInfoChild version;
#Before
public void setUp() throws Exception {
this.version = new ArtifactoryFolderInfoChild();
this.version.setUri("2.1.0");
this.version.setFolder(true);
when(restTemplateBuilder.build()).thenReturn(restTemplate);
}
#Test
public void testCoreVersionsJsonHandle() throws Exception{
when(restTemplate.getForObject("https://openmrs.jfrog.io/openmrs/api/storage/public/org/openmrs/api/openmrs-api/",
String.class))
.thenReturn(getFileAsString("core-versions.json"));
("2.1.0"));*/
}
This is the core-versions.json . This is nothing else but the data received from this Rest API.
Basically I'm trying to run a test and I have a spring schedule that will parse the json received from that Rest url. Now, while testing the schedule, I want to return the same data but without connecting to the internet and hence want to return the contents of core-versions.json. I get the following error unfortunately :
java.lang.IllegalStateException: File downloaded from could not be parsed
My schedule class is this:
#Component
public class FetchCoreVersionsList {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String[] STRINGS_TO_EXCLUDE = {"alpha", "beta", "RC", "SNAPSHOT"};
#Value("${core_version_list.url}")
private String url;
//#Value("${core_version_list.strategy}")
//private FetchCoreVersionsList.Strategy strategy = FetchCoreVersionsList.Strategy.FETCH;
private RestTemplateBuilder restTemplateBuilder;
private ObjectMapper mapper;
private VersionsService versionsService;
#Autowired
public FetchCoreVersionsList(RestTemplateBuilder restTemplateBuilder,
ObjectMapper mapper,
VersionsService versionsService) {
this.restTemplateBuilder = restTemplateBuilder;
this.mapper = mapper;
this.versionsService = versionsService;
}
#Scheduled(
initialDelayString = "${scheduler.fetch_core_versions_list.initial_delay}",
fixedDelayString = "${scheduler.fetch_core_versions_list.period}")
public void fetchCoreVersionsList() throws Exception {
logger.info("Fetching list of OpenMRS-Core versions");
// FetchCoreVersionsList.Strategy strategy = FetchCoreVersionsList.Strategy.FETCH;
String json;
/* if (strategy == Strategy.LOCAL) {
logger.debug("LOCAL strategy");
json = StreamUtils.copyToString(getClass().getClassLoader().getResourceAsStream("openmrs-core-versions.json"),
Charset.defaultCharset());
} else {*/
json = restTemplateBuilder.build().getForObject(url, String.class);
logger.info("FETCH strategy: " + json);
ArtifactoryFolderInfo versionlist;
try { logger.info("FETCH strategy: " + json);
logger.debug("papa strategy: " + url);
versionlist = mapper.readValue(json, ArtifactoryFolderInfo.class);
} catch (Exception ex) {
throw new IllegalStateException("File downloaded from " + url + " could not be parsed", ex);
}
if (logger.isInfoEnabled()) {
logger.info("There are " + versionlist.getChildren().size() + " openmrs-core versions");
}
if (versionlist.size() > 0) {
List<String> versions = new ArrayList<>();
List<ArtifactoryFolderInfoChild> allversions = versionlist.getChildren();
for (ArtifactoryFolderInfoChild candidateVersion : allversions) {
if (candidateVersion.getFolder() && !stringContainsItemFromList(candidateVersion.getUri(), STRINGS_TO_EXCLUDE)) {
versions.add(candidateVersion.getUri().replaceAll("/", ""));
}
}
versionsService.setVersions(versions);
} else {
logger.warn("File downloaded from " + url + " does not list any Core Versions to index. Keeping our current list");
}
}
private static boolean stringContainsItemFromList(String inputStr, String[] items) {
return Arrays.stream(items).parallel().anyMatch(inputStr::contains);
}
public enum Strategy {
FETCH, LOCAL
}
}
Kindly bear with me if this is a silly error as I am completely new to testing.