0

I'm testing my Rest APIs on Postman and URL in browser, but I don't know how to test an API with a POST method that takes an object as a parameter. I know there is nothing wrong with my code because it is part of Hyperskill projects and it passed all the tests. It's really just I dont know how to test it and I can't find an answer anywhere.

Here is what I should test and what results I should get:

Request body:

{
    "row": 3,
    "column": 4
}

Response body:

{
    "row": 3,
    "column": 4,
}

When I try the same Request body again:

{
    "row": 3,
    "column": 4
}

Response body should give me an error message:

{
    "error": "The ticket has been already purchased!"
}

Instead when I test following URL http://localhost:28852/purchase?row=3&column=4 in browser I get:

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Jan 23 08:53:33 CET 2023 There was an unexpected error (type=Method Not Allowed, status=405).

When I try to test my code in Postman I get: enter image description here

And here's my full code in Java:

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
@RestController
public class SeatController {
    public SeatController() {}
        private ScreenRoom screenRoom = new ScreenRoom(9, 9);
        @GetMapping("/seats")
        public ScreenRoom getSeat(){
            return screenRoom;
        }

    @PostMapping("/purchase")
    public synchronized ResponseEntity<?> postSeat(@RequestBody Seat seat){
        if (seat.getRow() < 1 || seat.getRow() > 9 || seat.getColumn() < 1 || seat.getColumn() > 9) {
            return new ResponseEntity<>(Map.of("error", "The number of a row or a column is out of bounds!"), HttpStatus.BAD_REQUEST);
        }
        if (screenRoom.getAvailable_seats().contains(seat)) {
            screenRoom.removeFromAvailableSeats(seat);
            return new ResponseEntity<>(seat, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(Map.of("error", "The ticket has been already purchased!"), HttpStatus.BAD_REQUEST);
        }
    }
}

public class ScreenRoom {
    private int total_rows;
    private int total_columns;
    private List<Seat> available_seats = new ArrayList<>();

    public ScreenRoom(int total_rows, int total_columns) {
        this.total_rows = total_rows;
        this.total_columns = total_columns;

        for (int i = 1; i <= total_rows; i++) {
            for (int j = 1; j <= total_columns; j++) {
                available_seats.add(new Seat(i, j));
            }
        }
    }
    public int getTotal_rows() {
        return total_rows;
    }
    public void setTotal_rows(int total_rows) {
        this.total_rows = total_rows;
    }
    public int getTotal_columns() {
        return total_columns;
    }
    public void setTotal_columns(int total_columns) {
        this.total_columns = total_columns;
    }
    public List<Seat> getAvailable_seats() {
        return available_seats;
    }
    public void setAvailable_seats(List<Seat> available_seats) {
        this.available_seats = available_seats;
    }
    public void removeFromAvailableSeats(Seat seat) {
        this.available_seats.remove(seat);
    }
    public void getSeat(Seat seat) {
        this.available_seats.get(this.available_seats.indexOf(seat));
    }
}
public class Seat {
    private int row;
    private int column;
    public Seat(int row, int column) {
        this.row = row;
        this.column = column;
    }
    public int getRow() {
        return row;
    }
    public void setRow(int row) {
        this.row = row;
    }
    public int getColumn() {
        return column;
    }
    public void setColumn(int column) {
        this.column = column;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Seat seat = (Seat) o;
        if (row != seat.row) return false;
        return column == seat.column;
    }
}

What exactly I'm doing wrong regarding testing? Thank you for your time and answers.

Michal
  • 229
  • 3
  • 11
  • 1
    What do you mean by testing in browser? You can't do POST requests in browser by just typing in the URL. The error (Method not allowed) implies that you are not doing a POST request, but instead a GET or something. You need to do an AJAX POST request with Javascript. Can you show how you are testing it via browser? – Tarmo Jan 23 '23 at 08:54
  • @Tarmo I test this URL http://localhost:28852/purchase?row=3&column=4 in browser. That's it. I didnt know I cant do POST requests in browser. – Michal Jan 23 '23 at 08:56
  • You can, but to do it, you need to create a HTML page which does AJAX request either natively or with some library. Then you can test it via that. Here's the native way to do it: https://stackoverflow.com/questions/6396101/pure-javascript-send-post-data-without-a-form. But I'd use some library like axios or fetch. Makes it a lot cleaner and easier. – Tarmo Jan 23 '23 at 09:00
  • And `row=3&column=4` doesn't work. Those are query parameters not request body. Two different things and one is not converted to anohter. – Tarmo Jan 23 '23 at 09:04
  • @Tarmo Ok. Thank you. Let's forget about testing in browser then and lets focus on testing in Postman. Would you know how to do it? – Michal Jan 23 '23 at 09:07
  • On of the reasons why you get `500` for POST request is because you don;t have a no arguments constructor in the `Seat ` class. – artiomi Jan 23 '23 at 09:08
  • Also. Any time you get a 500, theres probably an error in your Spring log which leads you to the actual root cause. – Tarmo Jan 23 '23 at 09:10
  • @artiomi "no arguments constructor in the Seat class" I don't think I follow you. Could you show me an example in Java? – Michal Jan 23 '23 at 09:13
  • 1
    @Michal here it is: `public Seat() {}` – artiomi Jan 23 '23 at 09:15
  • @artiomi OMG that was it :) Now it works just as it should in Postman. Thank you very much! – Michal Jan 23 '23 at 09:18

1 Answers1

0

You can't do a POST from a browser, except via a js fetch. You can only a GET. The "Method Not Allowed, status=405 error" is telling you that, ie GET not allowed.

The error you get from postman shows you got past the 405 (because it is a POST) but the server is throwing and exception. You need to check logs or step through in debug.

John Williams
  • 4,252
  • 2
  • 9
  • 18