package org.webpieces.webserver.dev;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.webpieces.compiler.api.CompileConfig;
import org.webpieces.devrouter.api.DevRouterModule;
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.templatingdev.api.DevTemplateModule;
import org.webpieces.templatingdev.api.TemplateCompileConfig;
import org.webpieces.util.file.VirtualFile;
import org.webpieces.util.file.VirtualFileImpl;
import org.webpieces.util.logging.Logger;
import org.webpieces.util.logging.LoggerFactory;
import org.webpieces.webserver.ResponseExtract;
import org.webpieces.webserver.WebserverForTest;
import org.webpieces.webserver.test.Asserts;
import org.webpieces.webserver.test.FullResponse;
import org.webpieces.webserver.test.MockResponseSender;
import com.google.inject.Module;
import com.google.inject.util.Modules;
public class TestDevRefreshPageWithNoRestarting {
private static final Logger log = LoggerFactory.getLogger(TestDevSynchronousErrors.class);
private RequestListener server;
private MockResponseSender socket = new MockResponseSender();
private File stashedExistingCodeDir;
private File existingCodeLoc;
private String userDir;
@Before
public void setUp() throws ClassNotFoundException, IOException {
Asserts.assertWasCompiledWithParamNames("test");
userDir = System.getProperty("user.dir");
log.info("running from dir="+userDir);
existingCodeLoc = new File(userDir+"/src/test/java/org/webpieces/webserver/dev/app");
//developers tend to exit their test leaving the code in a bad state so if they run it again, restore the original
//version for them(if we change the original version, we have to copy it to this directory as well though :(
File original = new File(userDir+"/src/test/devServerTest/devServerOriginal");
FileUtils.copyDirectory(original, existingCodeLoc, null);
//cache existing code for use by teardown...
stashedExistingCodeDir = new File(System.getProperty("java.io.tmpdir")+"/webpiecesTestDevServer/app");
FileUtils.copyDirectory(existingCodeLoc, stashedExistingCodeDir);
//list all source paths here as you add them(or just create for loop)
//These are the list of directories that we detect java file changes under
List<VirtualFile> srcPaths = new ArrayList<>();
srcPaths.add(new VirtualFileImpl(userDir+"/src/test/java"));
VirtualFile metaFile = new VirtualFileImpl(userDir + "/src/test/resources/devMeta.txt");
log.info("LOADING from meta file="+metaFile.getCanonicalPath());
//html and json template file encoding...
TemplateCompileConfig templateConfig = new TemplateCompileConfig(srcPaths);
//java source files encoding...
CompileConfig devConfig = new CompileConfig(srcPaths);
Module platformOverrides = Modules.combine(
new DevRouterModule(devConfig),
new DevTemplateModule(templateConfig),
new MockFrontEndModule());
WebserverForTest webserver = new WebserverForTest(platformOverrides, null, false, metaFile);
server = webserver.start();
}
@After
public void tearDown() throws IOException {
//delete any modifications and restore the original code...
FileUtils.deleteDirectory(existingCodeLoc);
FileUtils.copyDirectory(stashedExistingCodeDir, existingCodeLoc);
}
@Test
public void testGuiceModuleAddAndControllerChange() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/home");
server.incomingRequest(req, new RequestId(0), true, socket);
verifyPageContents("user=Dean Hiller");
simulateDeveloperMakesChanges("src/test/devServerTest/guiceModule");
server.incomingRequest(req, new RequestId(0), true, socket);
verifyPageContents("newuser=Joseph");
}
//Different than swapping out meta
@Test
public void testJustControllerChanged() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/home");
server.incomingRequest(req, new RequestId(0), true, socket);
verifyPageContents("user=Dean Hiller");
simulateDeveloperMakesChanges("src/test/devServerTest/controllerChange");
server.incomingRequest(req, new RequestId(0), true, socket);
verifyPageContents("user=CoolJeff");
}
@Test
public void testRouteAdditionWithNewControllerPath() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/newroute");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_404_NOTFOUND);
simulateDeveloperMakesChanges("src/test/devServerTest/routeChange");
server.incomingRequest(req, new RequestId(0), true, socket);
verifyPageContents("Existing Route Page");
}
@Test
public void testFilterChanged() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/filter");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
Assert.assertEquals("http://myhost.com/home", response.getRedirectUrl());
simulateDeveloperMakesChanges("src/test/devServerTest/filterChange");
server.incomingRequest(req, new RequestId(0), true, socket);
response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
Assert.assertEquals("http://myhost.com/causeError", response.getRedirectUrl());
}
@Test
public void testNotFoundDisplaysWithIframeANDSpecialUrl() {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/notFound");
server.incomingRequest(req, new RequestId(0), true, socket);
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_404_NOTFOUND);
//platform should convert request into a development not found page which has an iframe
//of the original page with a query param to tell platform to display original
//page requested
response.assertContains("<iframe src=\"/notFound?webpiecesShowPage=true");
}
@Test
public void testNotFoundFilterNotChangedAndTwoRequests() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/anyNotFound?webpiecesShowPage");
server.incomingRequest(req, new RequestId(0), true, socket);
verify404PageContents("value1=something1");
server.incomingRequest(req, new RequestId(0), true, socket);
verify404PageContents("value1=something1");
}
@Test
public void testNotFoundRouteModifiedAndControllerModified() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/anyNotfound?webpiecesShowPage=true");
server.incomingRequest(req, new RequestId(0), true, socket);
verify404PageContents("value1=something1");
simulateDeveloperMakesChanges("src/test/devServerTest/notFound");
server.incomingRequest(req, new RequestId(0), true, socket);
verify404PageContents("value2=something2");
}
@Test
public void testNotFoundFilterModified() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/enableFilter?webpiecesShowPage=true");
server.incomingRequest(req, new RequestId(0), true, socket);
verify303("http://myhost.com/home");
simulateDeveloperMakesChanges("src/test/devServerTest/notFound");
server.incomingRequest(req, new RequestId(0), true, socket);
verify303("http://myhost.com/filter");
}
private void verify303(String url) {
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_303_SEEOTHER);
Assert.assertEquals(url, response.getRedirectUrl());
}
@Test
public void testInternalErrorModifiedAndControllerModified() throws IOException {
HttpRequest req = Requests.createRequest(KnownHttpMethod.GET, "/causeError");
server.incomingRequest(req, new RequestId(0), true, socket);
verify500PageContents("InternalError1=error1");
simulateDeveloperMakesChanges("src/test/devServerTest/internalError");
server.incomingRequest(req, new RequestId(0), true, socket);
verify500PageContents("InternalError2=error2");
}
private void simulateDeveloperMakesChanges(String directory) throws IOException {
File srcDir = new File(userDir+"/"+directory);
FileUtils.copyDirectory(srcDir, existingCodeLoc, null, false);
}
private void verifyPageContents(String contents) {
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_200_OK);
response.assertContains(contents);
}
private void verify404PageContents(String contents) {
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_404_NOTFOUND);
response.assertContains(contents);
}
private void verify500PageContents(String contents) {
FullResponse response = ResponseExtract.assertSingleResponse(socket);
response.assertStatusCode(KnownStatusCode.HTTP_500_INTERNAL_SVR_ERROR);
response.assertContains(contents);
}
}