Deleting Records and getting (SyntaxError: Unexpected end of input) - ember-data

I am getting this above when deleting a record.
SyntaxError: Unexpected end of input
Here is the request:
Remote Address:127.0.0.1:8085
Request URL:http://localhost:8085/myproject/rest/bookingVehicles/100
Request Method:DELETE
Status Code:200 OK
Here is the java method I am using:
I have tried this:
#RequestMapping(value = "{id}",
method = RequestMethod.DELETE,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.OK)
public void delete(#Min(1) #PathVariable("id") final long id) {
bookingVehicleDao.delete(id);
}
And this:
#RequestMapping(value = "{id}",
method = RequestMethod.DELETE,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.ACCEPTED)
public String delete(#Min(1) #PathVariable("id") final long id) {
bookingVehicleDao.delete(id);
return "";
}
And this:
#RequestMapping(value = "{id}",
method = RequestMethod.DELETE)
#ResponseStatus(HttpStatus.ACCEPTED)
public String delete(#Min(1) #PathVariable("id") final long id) {
bookingVehicleDao.delete(id);
return "";
}
Each time I am getting this error. Doing a .then() on the result never runs because according to ember-data an error has occurred. I am thinking maybe is has something to do with the HttpStatus. What is the correct HTTP code for a DELETE?
On the server side the records is correctly deleted so it is definately something to do with the response that it is not liking.

Found the issue, you need to return #ResponseStatus(HttpStatus.NO_CONTENT)
So:
#RequestMapping(value = "{id}",
method = RequestMethod.DELETE)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(#Min(1) #PathVariable("id") final long id) {
bookingVehicleDao.delete(id);
}

Related

FakeItEasy ControllerTest HttpGet Calls

I want to start using FakeItEasy for testing queries.
The tests I want to write should check if entities are returned on HttpGet calls (get all and get by Id)
The Controller:
public class ToDoController : ControllerBase
{
private readonly IMediator _mediator;
public ToDoController(IMediator mediator) =>
_mediator = mediator;
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<ToDoItem>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<ToDoItem>>> Get()
{
var result = await _mediator.Send(new ToDoItemsQuery(new
AllToDoItems())).ConfigureAwait(false);
if (result != null && result.Any())
{
return result.ToList();
}
throw new InvalidOperationException("TODO: error handling");
}
[HttpGet]
[Route("{id}")]
[Produces("application/json")]
[ProducesResponseType(typeof(ToDoItem), (int)HttpStatusCode.OK)]
public async Task<ActionResult<ToDoItem>> GetById(int itemId)
{
var result = await _mediator
.Send(new ToDoItemsQuery(new ToDoItemById(itemId)))
.ConfigureAwait(false);
if (result != null && result.Any())
{
return result.FirstOrDefault();
}
throw new InvalidOperationException("TODO: error handling");
}
}
}
The TestClass:
public class ToDoItemControllerTests : ControllerTestBase
{
private IMediator _mediator;
private ToDoController _sut;
public ToDoItemControllerTests()
{
_mediator = A.Fake<IMediator>();
_sut = new ToDoController(_mediator);
}
[TestMethod]
public async Task GetAllItemsAsync_SuccessTest()
{
A.CallTo(() => _mediator.Send(A<AllToDoItems>._,
A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
var result = await _sut.Get();
Assert.IsNotNull(result);
A.CallTo(() => _mediator).MustHaveHappened();
}
[TestMethod]
public async Task GetItemByIdAsync_SuccessTest()
{
// Arrange
int itemId = 2;
var commandResult =
new List<ToDoItem>
{
new ToDoItem
{
Id = itemId
};
}
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).Returns(commandResult);
// Act
var result = await _sut.GetById(itemId);
// Assert
Assert.IsNotNull(result);
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).MustHaveHappened();
}
}
So in the first test I set up A.CallTo the interface IMediatR to return 10 ToDoItems.
During debug I see the _sut.Get() enter the controller, entering the correct method/api call.
The _mediator.Send() in the controller returns a Fake IEnumerable (not the 10 items i set up in the first Call.To in the testmethod, but an enumeration that yields no results).
Because of the result.Any() being false, the controller throws an InvalidOperationException
And I cannot even Assert the result.IsNotNull()
The second test I want to Test If 1 item is returned upon calling the API.
I set up (a) an itemId of type int for parameter,
(b) A mocked(?) List with 1 Item from the setup with the itemId and
(c) a call to the mediatR should return the mocked Listfrom (b)
I make the call from the test, in debug I see the call await _mediator.Sent() returning
A Fake Ienumerable of ToDoItem, result is not null, but because result.Any() is false,
the item doesn't get returned, and I get another InvalidOperationException
I feel like I'm missing something in the setup of the tests..
A Fake database Interface?
I don't want to chance my controller and make the if less restrictive, just so my test would pass
EDIT:
Even if I change the if condition to removing the Any condition
and I see the test entering the controller, returning "First Or Default" of the result,
The test fails on A Call To Must Have Happened.
Expected to find it once or more but no calls were made to the fake object.
This I really don't get, i actually see him making the call?!
I've browsed GitHub to find examples but the closest I found was Entities with methods, with those methods being defined in an interface. This is not the case here
Seeing as the official documentation doesn't make me any wiser I turn to SO <3
Thanks in advance!
In the first test, you configure the call to Send with an argument of type AllToDoItems. But in the controller, you actually call Send with a TodoItemsQuery. So the call doesn't match, and the default (unconfigured) behavior, which is to return a fake IEnumerable, applies. You need to configure the call like this:
A.CallTo(() => _mediator.Send(A<TodoItemsQuery>._,
A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
In the second test, the problem is the same, with ToDoItemById instead of AllToDoItems

Testng - Skip dependent tests for only failed data sets

I am attempting to modify my dependent tests so they are ran in a specific way and have yet find a way possible. For instance, say I have the following two tests and the defined data provider:
#Dataprovider(name = "apiResponses")
Public void queryApi(){
return getApiResponses().entrySet().stream().map(response -> new Object[]{response.getKey(), response.getValue()}).toArray(Object[][]::new);
}
#Test(dataprovider = "apiResponses")
Public void validateApiResponse(Object apiRequest, Object apiResponse){
if(apiResponse.statusCode != 200){
Assert.fail("Api Response must be that of a 200 to continue testing");
}
}
#Test(dataprovider = "apiResponses", dependsOnMethod="validateApiResponse")
Public void validateResponseContent(Object apiRequest, Object apiResponse){
//The following method contains the necessary assertions for validating api repsonse content
validateApiResponseData(apiResponse);
}
Say I have 100 api requests I want to validate, with the above, if a single one of those 100 requests were to return a status code of anything other than 200, then validateResponseContent would be skipped for all 100. What I'm attempting to achieve is that the dependent tests would be skipped for only the api responses that were to return without a status code of 200 and for all tests to be ran for responses that returned WITH a status code of 200.
You should be using a TestNG Factory which creates instances with both the apiRequest and apiResponse in it for each instance. Now each instance would basically first run an assertion on the status code before it moves on to validating the actual api response.
Here's a sample that shows how this would look like:
public class TestClassSample {
private Object apiRequest, apiResponse;
#Factory(dataProvider = "apiResponses")
public TestClassSample(Object apiRequest, Object apiResponse) {
this.apiRequest = apiRequest;
this.apiResponse = apiResponse;
}
#Test
public void validateApiResponse() {
Assert.assertEquals(apiResponse.statusCode, 200, "Api Response must be that of a 200 to continue testing");
}
#Test(dependsOnMethods = "validateApiResponse")
public void validateResponseContent() {
//The following method contains the necessary assertions for validating api repsonse content
validateApiResponseData(apiResponse);
}
#DataProvider(name = "apiResponses")
public static java.lang.Object[][] queryApi() {
return getApiResponses().entrySet()
.stream().map(
response -> new java.lang.Object[]{
response.getKey(), response.getValue()
})
.toArray(Object[][]::new);
}
}
Would'nt adding a if/else block solve this?
#Test(dataprovider = "apiResponses")
Public void validateApiResponse(Object apiRequest, Object apiResponse){
if(apiResponse.statusCode != 200){
Assert.fail("Api Response must be that of a 200 to continue testing");
} else {
validateApiResponseData(apiResponse);
}
}

Trying to use PlaceRequest the right way

i have two Presenters: A DevicePresenter and a ContainerPresenter. I place a PlaceRequest in the DevicePresenter to call the ContainerPresenter with some parameters like this:
PlaceRequest request = new PlaceRequest.Builder()
.nameToken("containersPage")
.with("action","editContainer")
.with("containerEditId", selectedContainerDto.getUuid().toString())
.build();
placeManager.revealPlace(request);
In my ContainersPresenter i have this overridden method:
#Override
public void prepareFromRequest(PlaceRequest placeRequest) {
Log.debug("prepareFromRequest in ContainersPresenter");
super.prepareFromRequest(placeRequest);
String actionString = placeRequest.getParameter("action", "");
String id;
//TODO: Should we change that to really retrieve the object from the server? Or should we introduce a model that keeps all values and inject that into all presenters?
if (actionString.equals("editContainer")) {
try {
id = placeRequest.getParameter("id", null);
for(ContainerDto cont : containerList) {
Log.debug("Compare " + id + " with " + cont.getUuid());
if(id.equals(cont.getUuid())) {
containerDialog.setCurrentContainerDTO(new ContainerDto());
addToPopupSlot(containerDialog);
break;
}
}
} catch (NumberFormatException e) {
Log.debug("id cannot be retrieved from URL");
}
}
}
But when revealPlace is called, the URL in the browser stays the same and the default presenter (Home) is shown instead.
When i print the request, it seems to be fine:
PlaceRequest(nameToken=containersPage, params={action=editContainer, containerEditId=8fa5f730-fe0f-11e3-a3ac-0800200c9a66})
And my NameTokens are like this:
public class NameTokens {
public static final String homePage = "!homePage";
public static final String containersPage = "!containersPage";
public static final String devicesPage = "!devicesPage";
public static String getHomePage() {
return homePage;
}
public static String getDevicesPage() {
return devicesPage;
}
public static String getContainersPage() {
return containersPage;
}
}
What did i miss? Thanks!
In your original code, when constructing your PlaceRequest, you forgot the '!' at the beginning of your nametoken.
.nameToken("containersPage")
while your NameTokens entry is
public static final String containersPage = "!containersPage";
As you noted, referencing the constant in NameTokens is less prone to such easy mistakes to make!
Sometimes the problem exists "between the ears". If i avoid strings but use the proper symbol from NameTokens like
PlaceRequest request = new PlaceRequest.Builder()
.nameToken(NameTokens.containersPage)
.with("action","editContainer")
.with("containerEditId", selectedContainerDto.getUuid().toString())
.build();
it works just fine. Sorry!

How to request same parameter twice in query string?

I am trying to request the following query string url: api/item?name=storm&name=prest
I am using the following code below and I cannot get the code to work.
public class ItemController : ApiController
{
private cdwEntities db = new cdwEntities();
public HttpResponseMessage Get([FromUri] Query query)
{
var data = db.database_ICs.AsQueryable();
if (query.name != null)
{
**data = data.Where(c => c.Name.Split("&").Contains(query.name));**
}
if (query.id!= null)
{
data = data.Where(c => c.ID== query.id);
}
if (!data.Any())
{
var message = string.Format("No data was found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
return Request.CreateResponse(HttpStatusCode.OK, data);
}
}
Any help would be very much appreciated.
You can use post Api and send array of [name].
name = [item1,item2....]
public void Post([FromBody] List<string> name) {
}
You can not pass same name key in Querystring. Browser/Code did not identified which is correct value, if you want multiple value then pass as a object.

Struts2 more than one action in one class

I'm using Struts2. I have two web forms that have the same code. I would like to eliminate one form. Here is the structure of my Struts project.
\Web Pages
form.jsp
\WEB-INF
\Content
error.jsp
form.jsp
success.jsp
\Source Packages
\action
MyAction.java
MyAction.java
package action;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.*;
public class MyAction extends ActionSupport {
#Action(value = "foo", results = {
#Result(name = "input", location = "form.jsp"),
#Result(name = "success", location = "success.jsp"),
#Result(name = "error", location = "error.jsp")
})
public String execute() throws Exception {
if (user.length() == 1) {
return "success";
} else {
return "error";
}
}
private String user = "";
public void validate() {
if (user.length() == 0) {
addFieldError("user", getText("user required"));
}
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
I tried to eliminate form.jsp under \Web Pages by adding a new action method to MyAction.java.
#Action(value="bar", results = {
#Result(name = "success", location = "form.jsp"),
})
public String another() {
return "success";
}
But I got the following error when I go to http : //localhost .../bar.action
HTTP Status 404 - No result defined for action action.MyAction and result input
Your MyAction has an implementation of validate(), which means it is validation aware.
What's happening is that you're calling another, but validate() is kicking in (as it's in the interceptor stack). Validation is failing, and therefore sending to INPUT result, which is not defined in another.
You should
Add #SkipValidation to the another method if you don't want validation there
Add the INPUT result to another() if you want a default input result
On a more general note, when you get that kind of error (No result defined for action X and result input) it usually means you're either having validation errors, parameter population errors (eg: an exception in preparable).