How to solve error code "405" on API call with testing? - java

I'm getting error code "405" while testing my API calls on run mode in IntelliJ. However when I test the API cal; with the same parameters in Postman it works.
I'm programming a jukebox where an user has to log in in order to use it. The login form works and when i try to log in with Postman it also logs in succesfull. However when i run my code on IntelliJ it gives me error code "405", which means "Method not allowed".
My userController class code which works:
#PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String login(#RequestBody MultiValueMap<String, String> body){
String email = body.getFirst("email");
String username = body.getFirst("username");
String password = body.getFirst("password");
return userService.loginUser(email, username, password);
}
My functional testing code(also works because my other GET methods in my API tests works):
public class FunctionalTest {
#BeforeClass
public static void setup() {
String port = System.getProperty("server.port");
if (port == null) {
RestAssured.port = Integer.valueOf(8080);
}
else{
RestAssured.port = Integer.valueOf(port);
}
String basePath = System.getProperty("server.base");
if(basePath==null){
basePath = "/";
}
RestAssured.basePath = basePath;
String baseHost = System.getProperty("server.host");
if(baseHost==null){
baseHost = "http://localhost";
}
RestAssured.baseURI = baseHost;
}
}
And finally my code for testing the POST method for logging in:
//User control
#Test
public void checkLogin(){
given()
.param("email", "123")
.param("username", "123")
.param("password", "123")
.when()
.get("/login")
.then()
.statusCode(200);
}
Hope anyone can help me solve this problem.
Thanks in advance!

405 means method not allowed. This is happening because you are exposing a POST operation (#PostMapping(value = "/login", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) but trying to consume by means of a GET: .when().get("/login")

Related

Get request error Springboot to Zillow Api

I'm trying to do a get request from Springboot to Zillow API but I'm getting an error below:
Error: no exact match found for input address
508
and this is my code
public String getZillow()
{
final String uri =
"https://www.zillow.com/webservice/GetSearchResults.htm&address=1756+Bluebird+Ct&citystatezip=Carrollton%2C+TX";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
return result;
}
#RequestMapping(value = "/zillow", produces = MediaType.APPLICATION_XML_VALUE, method = RequestMethod.GET)
public String getAllEmployeesXML()
{
return getZillow();
}
I was able to see the xml object successfully with the uri address on the browser but not on Springboot.

Spring Boot test API endpoint with unit testing should return 404 instead of 400

I have the following controller on my Spring Boot application, which is connected to a MongoDB:
#RestController
#RequestMapping("/experts")
class ExpertController {
#Autowired
private ExpertRepository repository;
#RequestMapping(value = "/", method = RequestMethod.GET)
public List<Experts> getAllExperts() {
return repository.findAll();
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Experts getExpertById(#PathVariable("id") ObjectId id) {
return repository.findBy_id(id);
}
I am trying to test the the get/id endpoint on my test, which I expect to give back an 404 response as shown below:
#Test
public void getEmployeeReturn404() throws Exception {
ObjectId id = new ObjectId();
mockMvc.perform(MockMvcRequestBuilders.get("/experts/999", 42L)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isNotFound());
}
Despite that, the response that comes back is 400, which means that my request is malformed. I guess the problem lies on the id, which I am inputting on the URI? I know that mongo accepts hexStrings as primary keys so my question is, how could I use an id on the URI which doesnt exist on my DB so that I can get a 404 response back? Thanks in advance for your answer.
"/experts/999", 42L
This is not an objectId.
Try something like
mockMvc.perform(MockMvcRequestBuilders.get("/experts/58d1c36efb0cac4e15afd278")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isNotFound());
For urlVariables, you need:
#Test
public void getEmployeeReturn404() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/experts/{id}", 42L)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isNotFound());
}
Where 42L is your {id} PathVariable value.

How to create a URL pointing to a REST endpoint in your system at runtime with Spring Boot?

I'm using Spring Boot to build a REST API. In my situation, there are 2 controllers: ExportController and ImportController. Please check the example code here:
Export Controller:
#RestController
public class ExportController {
#GetMapping(value = "/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<Resource> export(#RequestParam("id") String id) {
// Processing...
}
}
Import Controller:
#RestController
public class ImportController {
#PostMapping(value = "/import", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> importData(HttpServletRequest request) {
// Processing...
// What should I do here?
String url = ...
}
}
Inside my ImportController, I want to generate a URL pointing to the /export endpoint, e.g. http://www.example.com/export?id=1234.
I don't configure anything about the host or port in the application.properties. I want to get them at runtime.
Could you please show me how to achieve it? I searched a lot on the Internet but couldn't find the answer. Thank you for your help.
If you can live with bringing spring-hateoas into your project then this will work:
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
#RestController
public class ImportController {
#PostMapping(value = "/import", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> importData(HttpServletRequest request) {
String someId = "1234";
ControllerLinkBuilder linkBuilder = ControllerLinkBuilder.linkTo(methodOn(ExportController.class).export(someId));
URI uri = linkBuilder.toUri();
return ResponseEntity.ok(uri);
}
}
This yields http://localhost:8080/export?id=1234
#RestController
public class ImportController {
#PostMapping(value = "/import", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> importData(HttpServletRequest request) {
// Processing...
String url = request.getScheme() + "://" +
request.getServerName() + ":" +
request.getServerPort() + "/export";
}
}
You can make use of ServletUriComponentsBuilder that comes with Spring framework since 3.1.RELEASE.
Given that you have access to current request, You can do something like below.
UriComponents uriComponents = ServletUriComponentsBuilder
.fromRequest(httpServletRequest)
.replacePath("/export")
.queryParam("id",1234)
.build();
String url = uriComponents.toUri();

Mocking 3rd party api for rest api functional testing

I need to test the functionality of rest end point using Rest Template.
Below is the dummy rest api i need to test
#GetMapping(value = "/test")
public String getText(){
RestTemplate restTemplate = new RestTemplate();
String value = restTemplate.getForObject("EXTERNALURL/helloWorld",String.class);
return value +" got the value";
}
I have the below test cases which hits the above rest end point
private void expectFixedData() {
MockServerClient mockServerClient = ClientAndServer.startClientAndServer("127.0.0.1",1080);
try {
mockServerClient.when(HttpRequest.request().withMethod("GET")
.withPath("/helloWorld"), Times.exactly(1))
.respond(HttpResponse.response().withStatusCode(200)
.withBody("{ 'incorrect username and password combination' }")
.withDelay(TimeUnit.SECONDS, 1));
}
finally{
mockServerClient.close();
}
}
#Test
public void callExternalService(){
expectFixedData();
RestTemplate restTemplate = new RestTemplate();
String value = restTemplate.getForObject("http://localhost:8080/test",String.class);
Assert.assertTrue(value.equals("incorrect username and password combination got the value"));
}
But when i run the test cases it still calls the external URL
Any help would be appreciated.
Was able to mock response for 3rd party using WireMock

How does a servlet get data from another servlet?

My problem like this:
I have two servlets:
servlet_A: http://localhost:8080/test/servlet_wait_for_response
servlet_B: http://localhost:8080/test/servlet_send_data?data=xxx
1. I use Firefox invoking servlet_A, and the servlet_A does nothing but wait;
2. I use Chrome invoking servlet_B, and send "helloworld" to the server, for example: http://localhost:8080/test/servlet_send_data?data=helloworld
3. servlet_B get the message "helloworld", then send this message to servlet_A;
4. servlet_A get the message "helloworld" from servlet_B, then response this message to Firefox.
I got an answer like below:
static String msg = null;
#RequestMapping(value = "/wait_for_data", method = RequestMethod.GET)
#ResponseBody
public String waitData() throws InterruptedException{
while(msg==null){
TimeUnit.SECONDS.sleep(1);
}
return msg;
}
#RequestMapping(value = "/send_data", method = RequestMethod.GET)
#ResponseBody
public String sendData(String data){
msg = data;
return "OK";
}

Categories