Package org.jamesdbloom.integration

Source Code of org.jamesdbloom.integration.SystemTest

package org.jamesdbloom.integration;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.Tomcat;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jamesdbloom.acceptance.login.LoginPage;
import org.jamesdbloom.acceptance.registration.RegistrationPage;
import org.jamesdbloom.acceptance.updatepassword.UpdatePasswordPage;
import org.jamesdbloom.email.NewRegistrationEmail;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;

import javax.mail.internet.MimeMessage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertThat;

/**
* @author jamesdbloom
*/
public class SystemTest {

    private static Tomcat tomcat;
    private static Wiser wiser;
    private static KeyStore trustStore;

    @BeforeClass
    public static void setupFixture() throws Exception {
        // setup mock smtp
        System.setProperty("email.host", "127.0.0.1");
        System.setProperty("email.port", "2500");
        System.setProperty("email.starttls", "false");
        wiser = new Wiser();
        wiser.setPort(2500);
        wiser.start();

        // determine current filesystem location
        String classLocation = SystemTest.class.getCanonicalName().replace(".", "/") + ".class";
        String projectBase = SystemTest.class.getClassLoader().getResource(classLocation).toString().replace(classLocation, "../../").replace("file:", "");

        // start proxy (in tomcat)
        tomcat = new Tomcat();
        tomcat.setBaseDir(new File(".").getCanonicalPath() + File.separatorChar + "tomcat");

        // add http port
        tomcat.setPort(8080);

        // add https port
        Connector httpsConnector = new Connector();
        httpsConnector.setPort(8443);
        httpsConnector.setSecure(true);
        httpsConnector.setScheme("https");
        httpsConnector.setAttribute("keystorePass", "changeit");
        httpsConnector.setAttribute("keystoreFile", projectBase + "keystore");
        httpsConnector.setAttribute("clientAuth", "false");
        httpsConnector.setAttribute("sslProtocol", "TLS");
        httpsConnector.setAttribute("SSLEnabled", true);
        Service service = tomcat.getService();
        service.addConnector(httpsConnector);

        // add servlet
        Context ctx = tomcat.addContext("/", projectBase + "src/main/webapp");
        ContextConfig contextConfig = new ContextConfig();
        ctx.addLifecycleListener(contextConfig);
        contextConfig.setDefaultWebXml(projectBase + "src/main/webapp/WEB-INF/web.xml");

        // control logging level
        java.util.logging.Logger.getLogger("").setLevel(Level.FINER);

        // start server
        tomcat.start();

        // load key store for certificates
        trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        try (FileInputStream fileInputStream = new FileInputStream(new File(projectBase + "keystore"))) {
            trustStore.load(fileInputStream, "changeit".toCharArray());
        }
    }

    @AfterClass
    public static void shutdownFixture() throws LifecycleException {
        // stop server
        tomcat.stop();

        // stop smtp mock
        wiser.stop();
    }

    @Test
    public void registerUpdatePasswordLoginAndViewPage() throws Exception {
        // given
        HttpClient httpClient = createApacheClient();

        // when - register
        HttpResponse registerPageResponse = httpClient.execute(new HttpGet("https://127.0.0.1:8443/register"));
        RegistrationPage registrationPage = new RegistrationPage(getBodyAndClose(registerPageResponse));
        registrationPage.shouldHaveCorrectFields();
        String csrf = registrationPage.csrfValue();

        HttpPost register = new HttpPost("https://127.0.0.1:8443/register");
        register.setEntity(new UrlEncodedFormEntity(Arrays.asList(
                new BasicNameValuePair("name", "test_user"),
                new BasicNameValuePair("email", "fake@email.com"),
                new BasicNameValuePair("_csrf", csrf)
        )));
        HttpResponse registerResponse = httpClient.execute(register);

        // then - should respond with success message
        assertThat(registerResponse.getStatusLine().getStatusCode(), is(HttpStatus.SC_MOVED_TEMPORARILY));
        assertThat(registerResponse.getFirstHeader("Location").getValue(), is("https://127.0.0.1:8443/message"));
        getBodyAndClose(registerResponse);

        // then - should have sent correct email
        TimeUnit.SECONDS.sleep(2);
        assertThat(wiser.getMessages(), is(not(empty())));
        WiserMessage registrationWiserMessage = wiser.getMessages().get(0);
        MimeMessage mimeMessage = registrationWiserMessage.getMimeMessage();
        NewRegistrationEmail registrationEmail = new NewRegistrationEmail(mimeMessage.getContent().toString());
        String updatePasswordURL = registrationEmail.shouldHaveCorrectFields("fake@email.com");

        // when - updating password
        HttpResponse updatePasswordPageResponse = httpClient.execute(new HttpGet(updatePasswordURL));
        UpdatePasswordPage updatePasswordPage = new UpdatePasswordPage(getBodyAndClose(updatePasswordPageResponse));
        updatePasswordPage.shouldHaveCorrectFields();
        csrf = updatePasswordPage.csrfValue();

        HttpPost updatePasswordRequest = new HttpPost(updatePasswordURL);
        updatePasswordRequest.setEntity(new UrlEncodedFormEntity(Arrays.asList(
                new BasicNameValuePair("password", "NewPassword123"),
                new BasicNameValuePair("passwordConfirm", "NewPassword123"),
                new BasicNameValuePair("_csrf", csrf)
        )));
        HttpResponse updatePasswordResponse = httpClient.execute(updatePasswordRequest);

        // then - should respond with success message
        assertThat(updatePasswordResponse.getStatusLine().getStatusCode(), is(HttpStatus.SC_MOVED_TEMPORARILY));
        assertThat(updatePasswordResponse.getFirstHeader("Location").getValue(), is("https://127.0.0.1:8443/message"));
        getBodyAndClose(updatePasswordResponse);

        // when - hit secured page
        HttpResponse landingPageResponse = httpClient.execute(new HttpGet("http://127.0.0.1:8080/"));

        // then - login page is displayed
        LoginPage securePageResponse = new LoginPage(getBodyAndClose(landingPageResponse));
        securePageResponse.shouldHaveCorrectFields();
        csrf = securePageResponse.csrfValue();

        // when - login is performed
        HttpPost login = new HttpPost("https://127.0.0.1:8443/login");
        login.setEntity(new UrlEncodedFormEntity(Arrays.asList(
                new BasicNameValuePair("username", "fake@email.com"),
                new BasicNameValuePair("password", "NewPassword123"),
                new BasicNameValuePair("_csrf", csrf)
        )));
        HttpResponse loginResponse = httpClient.execute(login);

        // then - secured page is displayed
        assertThat(loginResponse.getStatusLine().getStatusCode(), is(HttpStatus.SC_MOVED_TEMPORARILY));
        assertThat(loginResponse.getFirstHeader("Location").getValue(), is("https://127.0.0.1:8443/"));
        getBodyAndClose(loginResponse);

        // when - logout
        httpClient = createApacheClient();
        HttpResponse logoutResponse = httpClient.execute(new HttpGet("https://127.0.0.1:8443/logout"));

        // then - should get redirected to login page
        LoginPage logoutRequestResponse = new LoginPage(getBodyAndClose(logoutResponse));
        logoutRequestResponse.shouldHaveCorrectFields();
    }

    private String getBodyAndClose(HttpResponse httpResponse) throws IOException {
        String body = EntityUtils.toString(httpResponse.getEntity());
        EntityUtils.consumeQuietly(httpResponse.getEntity());
        return body;
    }

    private CloseableHttpClient createApacheClient() throws Exception {
        return HttpClients.custom()
                // make sure the tests don't block when server fails to start up
                .setDefaultSocketConfig(SocketConfig.custom()
                        .setSoTimeout((int) TimeUnit.SECONDS.toMillis(4))
                        .build())
                .setSslcontext(
                        SSLContexts
                                .custom()
                                .loadTrustMaterial(trustStore, new TrustStrategy() {
                                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                                        return true;
                                    }
                                })
                                .build()
                )
                .setHostnameVerifier(new AllowAllHostnameVerifier())
                .build();
    }
}
TOP

Related Classes of org.jamesdbloom.integration.SystemTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.