package org.webpieces.webserver.beans;
import java.util.List;
import java.util.concurrent.Executor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.webpieces.data.api.DataWrapper;
import org.webpieces.data.api.DataWrapperGenerator;
import org.webpieces.data.api.DataWrapperGeneratorFactory;
import org.webpieces.httpcommon.Requests;
import org.webpieces.httpcommon.api.RequestId;
import org.webpieces.httpcommon.api.RequestListener;
import org.webpieces.httpparser.api.dto.HttpRequest;
import org.webpieces.httpparser.api.dto.KnownHttpMethod;
import org.webpieces.httpparser.api.dto.KnownStatusCode;
import org.webpieces.mock.lib.MockExecutor;
import org.webpieces.util.file.VirtualFileClasspath;
import org.webpieces.webserver.ResponseExtract;
import org.webpieces.webserver.WebserverForTest;
import org.webpieces.webserver.basic.app.biz.SomeLib;
import org.webpieces.webserver.basic.app.biz.SomeOtherLib;
import org.webpieces.webserver.basic.app.biz.UserDto;
import org.webpieces.webserver.mock.MockSomeLib;
import org.webpieces.webserver.mock.MockSomeOtherLib;
import org.webpieces.webserver.test.FullResponse;
import org.webpieces.webserver.test.MockResponseSender;
import org.webpieces.webserver.test.PlatformOverridesForTest;
import com.google.inject.Binder;
import com.google.inject.Module;
public class TestBeans {
private RequestListener server;
private MockResponseSender socket = new MockResponseSender();
private MockSomeLib mockSomeLib = new MockSomeLib();
private MockSomeOtherLib mockSomeOtherLib = new MockSomeOtherLib();
private MockExecutor mockExecutor = new MockExecutor();
@Before
public void setUp() {
VirtualFileClasspath metaFile = new VirtualFileClasspath("beansMeta.txt", WebserverForTest.class.getClassLoader());
WebserverForTest webserver = new WebserverForTest(new PlatformOverridesForTest(), new AppOverridesModule(), false, metaFile);
server = webserver.start();
}
@Test
public void testPageParam() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/pageparam");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_200_OK);
response.assertContains("Hi Dean Hiller, this is testing");
response.assertContains("Or we can try to get a flash: testflashvalue");
}
@Test
public void testPageParamAsync() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/pageparam_async");
server.incomingRequest(req, new RequestId(0), true, socket);
Runnable runnable = mockExecutor.getRunnablesScheduled().get(0);
runnable.run();
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_200_OK);
response.assertContains("Hi Dean Hiller, this is testing");
response.assertContains("Or we can try to get a flash: testflashvalue");
}
@Test
public void testPostFailDueToSecureTokenCheck() {
HttpRequest req = Requests.createPostRequest("/postuser",
"user.firstName", "D&D",
"user.lastName", "Hiller",
"user.fullName", "Dean Hiller",
"user.address.zipCode", "555",
"user.address.street", "Coolness Dr.");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
//We should change this to a 400 bad request
response.assertStatusCode(KnownStatusCode.HTTP_500_INTERNAL_SVR_ERROR);
}
@Test
public void testComplexBeanSaved() {
HttpRequest req = Requests.createPostRequest("/postuser2",
"user.firstName", "D&D",
"user.lastName", "Hiller",
"user.fullName", "Dean Hiller",
"user.address.zipCode", "555",
"user.address.street", "Coolness Dr.");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
UserDto user = mockSomeOtherLib.getUser();
Assert.assertEquals(555, user.getAddress().getZipCode());
Assert.assertEquals("D&D", user.getFirstName());
Assert.assertEquals("Coolness Dr.", user.getAddress().getStreet());
}
/**
* Found this bug where it blew up translating 'null' to 'null' and tried to convert it
* to int instead, so added test then fixed
*/
@Test
public void testNullIdFromForm() {
HttpRequest req = Requests.createPostRequest("/postuser2",
"user.id", "" //multipart is "" and nearly all webservers convert that to null(including ours)
);
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
//should not have any errors and should redirect back to list of users page..
Assert.assertEquals("http://myhost.com/listusers", response.getRedirectUrl());
}
@Test
public void testInvalidComplexBean() {
HttpRequest req = Requests.createPostRequest("/postuser2",
"user.firstName", "D&D",
"user.lastName", "Hiller",
"user.fullName", "Dean Hiller",
"user.address.zipCode", "This test value invalid since not an int",
"user.address.street", "Coolness Dr.",
"password", "should be hidden from flash");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
UserDto savedUser = mockSomeOtherLib.getUser();
Assert.assertEquals(null, savedUser); //user was not
UserDto user = mockSomeLib.getUser();
Assert.assertEquals(0, user.getAddress().getZipCode()); //this is not set since it was invalid
Assert.assertEquals("D&D", user.getFirstName());
Assert.assertEquals("Coolness Dr.", user.getAddress().getStreet());
}
@Test
public void testArrayForm() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/arrayForm");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_200_OK);
response.assertContains("value=`FirstAccName`".replace('`', '"'));
response.assertContains("value=`SecondAccName`".replace('`', '"'));
response.assertContains("value=`someStreet2-0`".replace('`', '"'));
response.assertContains("value=`someStreet2-1`".replace('`', '"'));
//default labels are there...
response.assertContains("First NameX");
response.assertContains("StreetX");
}
@Test
public void testIncomingRequestAndDataSeperate() {
HttpRequest req = Requests.createPostRequest("/postArray2",
"user.accounts[1].name", "Account2Name",
"user.accounts[1].color", "green",
"user.accounts[2].addresses[0].number", "56",
"user.firstName", "D&D",
"user.lastName", "Hiller",
"user.fullName", "Dean Hiller"
);
DataWrapper data = req.getBody();
DataWrapperGenerator dataGen = DataWrapperGeneratorFactory.createDataWrapperGenerator();
// Split the body in half
List<? extends DataWrapper> split = dataGen.split(data, data.getReadableSize() / 2);
req.setBody(dataGen.emptyWrapper());
RequestId id = new RequestId(0);
server.incomingRequest(req, id, false, socket);
server.incomingData(split.get(0), id, false, socket);
server.incomingData(split.get(1), id, true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
UserDto user = mockSomeLib.getUser();
Assert.assertEquals("D&D", user.getFirstName());
Assert.assertEquals(3, user.getAccounts().size());
Assert.assertEquals("Account2Name", user.getAccounts().get(1).getName());
Assert.assertEquals(56, user.getAccounts().get(2).getAddresses().get(0).getNumber());
}
@Test
public void testArraySaved() {
HttpRequest req = Requests.createPostRequest("/postArray2",
"user.accounts[1].name", "Account2Name",
"user.accounts[1].color", "green",
"user.accounts[2].addresses[0].number", "56",
"user.firstName", "D&D",
"user.lastName", "Hiller",
"user.fullName", "Dean Hiller"
);
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
UserDto user = mockSomeLib.getUser();
Assert.assertEquals("D&D", user.getFirstName());
Assert.assertEquals(3, user.getAccounts().size());
Assert.assertEquals("Account2Name", user.getAccounts().get(1).getName());
Assert.assertEquals(56, user.getAccounts().get(2).getAddresses().get(0).getNumber());
}
/*
* Have the controller method be postUser(UserDbo user, String password) BUT then in the html have
* entity.name, entity.age, entity.password INSTEAD of user.name, etc. such that there
* is a mismatch and verify there is a clean error for that
*
* GET /adduser HTTP/1.1
* Host: localhost:59786
* User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:47.0) Gecko/20100101 Firefox/47.0
* Accept: text/html,application/xhtml+xml,application/xml;q=0.9,XX/XX;q=0.8
* Accept-Language: en-US,en;q=0.5
* Accept-Encoding: gzip, deflate
* Referer: http://localhost:59786/adduser
* Cookie: webSession=1-gzvc03bKRP2YYvWySwgENREwFSg=:__ST=3a2fda5dad7547d3b15b1f61bd3d12f5; webFlash=1:_message=Invalid+values+below&user.address.zipCode=Text+instead+of+number&__secureToken=3a2fda5dad7547d3b15b1f61bd3d12f5&user.firstName=Dean+Hiller; webErrors=1:user.address.zipCode=Could+not+convert+value
* Connection: keep-alive
*/
@Test
public void testDeveloperMistypesBeanNameVsFormNames() {
HttpRequest req = Requests.createPostRequest("/postuser",
"entity.firstName", "D&D",
"entity.lastName", "Hiller",
"entity.fullName", "Dean Hiller",
"password", "hi"
);
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_500_INTERNAL_SVR_ERROR);
}
@Test
public void testDeveloperMistypesBeanNameVsFormNamesButNullableIsUsed() {
HttpRequest req = Requests.createPostRequest("/postusernullable",
"entity.firstName", "D&D",
"entity.lastName", "Hiller",
"entity.fullName", "Dean Hiller",
"password", "hi"
);
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
}
@Test
public void testQueryParamsToUserBean() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/getuser");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_404_NOTFOUND);
}
@Test
public void testBeanMissingForGetSoNotFoundResults() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/getuser?user.firstName=jeff&password=as");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
}
private class AppOverridesModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(SomeOtherLib.class).toInstance(mockSomeOtherLib);
binder.bind(SomeLib.class).toInstance(mockSomeLib);
binder.bind(Executor.class).toInstance(mockExecutor);
}
}
}