org.eclipse.orion.server.tests.prefs.PreferenceTest.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.tests.prefs.PreferenceTest.java

Source

/*******************************************************************************
 * Copyright (c) 2010, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.orion.server.tests.prefs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.orion.internal.server.core.IOUtilities;
import org.eclipse.orion.server.core.OrionConfiguration;
import org.eclipse.orion.server.tests.servlets.files.FileSystemTest;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.PutMethodWebRequest;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;

/**
 * Tests for the preference servlet.
 */
public class PreferenceTest extends FileSystemTest {

    @Before
    public void setUp() throws Exception {
        clearWorkspace();
        List<String> userIds = OrionConfiguration.getMetaStore().readAllUsers();
        for (String userId : userIds) {
            OrionConfiguration.getMetaStore().deleteUser(userId);
        }
        webConversation = new WebConversation();
        webConversation.setExceptionsThrownOnErrorStatus(false);
        setUpAuthorization();
        createTestProject("PreferenceTest");
    }

    /**
     * Tests corruption of preference keys containing URLS.
     */
    @Test
    public void testBug409792() throws JSONException, IOException {
        String location = toAbsoluteURI("prefs/user/" + getTestUserId() + "/testBug409792");
        //put a value containing a URL in the key
        JSONObject prefs = new JSONObject();
        final String key = "http://127.0.0.2:8080/plugins/samplePlugin.html";
        prefs.put(key, true);
        WebRequest request = new PutMethodWebRequest(location, IOUtilities.toInputStream(prefs.toString()),
                "application/json");
        setAuthentication(request);
        WebResponse response = webConversation.getResource(request);
        assertEquals("1.1", HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

        //attempt to retrieve the preference
        request = new GetMethodWebRequest(location);
        setAuthentication(request);
        response = webConversation.getResource(request);
        assertEquals("1.2", HttpURLConnection.HTTP_OK, response.getResponseCode());
        JSONObject result = new JSONObject(response.getText());
        assertTrue("1.3", result.optBoolean(key));
    }

    @Test
    public void testGetSingle() throws IOException, JSONException {
        List<String> locations = getTestPreferenceNodes();
        for (String location : locations) {
            //unknown key should return 404
            WebRequest request = new GetMethodWebRequest(location + "?key=Name");
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NOT_FOUND, response.getResponseCode());

            //put a value
            request = createSetPreferenceRequest(location, "Name", "Frodo");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("2." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //now doing a get should succeed
            request = new GetMethodWebRequest(location + "?key=Name");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("3." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject result = new JSONObject(response.getText());
            assertEquals("4." + location, "Frodo", result.optString("Name"));

            //getting another key on the same resource should still 404
            request = new GetMethodWebRequest(location + "?key=Address");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("5." + location, HttpURLConnection.HTTP_NOT_FOUND, response.getResponseCode());
        }
    }

    @Test
    public void testPutSingle() throws IOException, JSONException {
        List<String> locations = getTestPreferenceNodes();
        for (String location : locations) {
            //put a value that isn't currently defined
            WebRequest request = createSetPreferenceRequest(location, "Name", "Frodo");
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //doing a get should succeed
            request = new GetMethodWebRequest(location + "?key=Name");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("2." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject result = new JSONObject(response.getText());
            assertEquals("3." + location, "Frodo", result.optString("Name"));

            //setting a value to the empty string
            request = createSetPreferenceRequest(location, "Name", "");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("4." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());
            request = new GetMethodWebRequest(location + "?key=Name");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("5." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            result = new JSONObject(response.getText());
            assertEquals("6." + location, "", result.optString("Name"));

            //putting with forbidden URL characters in key and value
            request = createSetPreferenceRequest(location, "Na=me", "Fr&do");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //doing a get should succeed
            request = new GetMethodWebRequest(location + "?key=Na%3Dme");
            setAuthentication(request);
            response = webConversation.getResource(request);
            result = new JSONObject(response.getText());
            assertEquals("3." + location, "Fr&do", result.optString("Na=me"));
        }
    }

    /**
     * Tests setting JSON objects as preference values
     * 
     * @throws IOException
     * @throws JSONException
     */
    @Test
    public void testPutJSON() throws IOException, JSONException {
        List<String> locations = getTestPreferenceNodes();
        for (String location : locations) {
            //PUT http://myserver:8080/prefs/user/cm/configurations/jslint.config
            //{"properties":{"options":"foo:true, bar:false"}}
            JSONObject value = new JSONObject();
            String options = "foo:true, bar:false";
            value.put("options", options);
            JSONObject prefs = new JSONObject();
            prefs.put("properties", value);
            String inString = prefs.toString();
            WebRequest request = new PutMethodWebRequest(location, IOUtilities.toInputStream(inString),
                    "application/json");
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //GET http://myserver:8080/prefs/user/cm/configurations/jslint.config
            //should return: same value we put in
            request = new GetMethodWebRequest(location);
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("2." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject resultObject = new JSONObject(response.getText());
            assertTrue("3." + location, resultObject.has("properties"));
            JSONObject resultValue = resultObject.getJSONObject("properties");
            Object resultOptions = resultValue.get("options");
            assertEquals("4." + location, options, resultOptions);

        }
        //
        //but...
        //
        //GET http://myserver:8080/prefs/user/cm/configurations/jslint.config
        //{
        //  "properties" : "{\"options\":\"foo:true, bar:false\"}"
        //}
    }

    @Test
    public void testPutNode() throws IOException, JSONException {
        List<String> locations = getTestPreferenceNodes();
        for (String location : locations) {
            //put a node that isn't currently defined
            JSONObject prefs = new JSONObject();
            prefs.put("Name", "Frodo");
            prefs.put("Address", "Bag End");
            WebRequest request = new PutMethodWebRequest(location, IOUtilities.toInputStream(prefs.toString()),
                    "application/json");
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //doing a get should succeed
            request = new GetMethodWebRequest(location + "?key=Address");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("2." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject result = new JSONObject(response.getText());
            assertEquals("3." + location, "Bag End", result.optString("Address"));

            //setting a node with disjoint values should clear values not in common
            prefs = new JSONObject();
            prefs.put("Name", "Barliman");
            prefs.put("Occupation", "Barkeep");
            request = new PutMethodWebRequest(location, IOUtilities.toInputStream(prefs.toString()),
                    "application/json");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("4." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());
            request = new GetMethodWebRequest(location);
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("5." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            result = new JSONObject(response.getText());
            assertEquals("6." + location, "Barliman", result.optString("Name"));
            assertFalse("7." + location, result.has("Address"));//this value was previously defined but the put node should clean it
            assertEquals("8." + location, "Barkeep", result.optString("Occupation"));
        }
    }

    @Ignore
    public void testDeleteSingle() {
        //TODO not implemented
    }

    @Ignore
    public void testDeleteNode() {
        //TODO not implemented
    }

    @Test
    public void testValueWithSpaces() throws IOException, JSONException {
        //put a value
        String location = getTestPreferenceNodes().get(0);
        WebRequest request = createSetPreferenceRequest(location, "Name", "Frodo Baggins");
        setAuthentication(request);
        WebResponse response = webConversation.getResource(request);
        assertEquals(HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

        //now doing a get should succeed
        request = new GetMethodWebRequest(location + "?key=Name");
        setAuthentication(request);
        response = webConversation.getResource(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
        JSONObject result = new JSONObject(response.getText());
        assertEquals("Frodo Baggins", result.optString("Name"));
    }

    /**
     * Tests whether a client can access workspace metadata via the preferences servlet.
     * @throws IOException 
     */
    @Test
    public void testAccessingMetadata() throws IOException {
        List<String> locations = getIllegalPreferenceNodes();
        for (String location : locations) {
            //get should return 405
            WebRequest request = new GetMethodWebRequest(location);
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals(HttpURLConnection.HTTP_BAD_METHOD, response.getResponseCode());

            //put a value should be 403
            request = createSetPreferenceRequest(location, "Name", "Frodo");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals(HttpURLConnection.HTTP_BAD_METHOD, response.getResponseCode());
        }
    }

    @Test
    public void testGetNode() throws IOException, JSONException {
        List<String> locations = getTestPreferenceNodes();
        for (String location : locations) {
            //unknown node should return 404
            WebRequest request = new GetMethodWebRequest(location);
            setAuthentication(request);
            WebResponse response = webConversation.getResource(request);
            assertEquals("1." + location, HttpURLConnection.HTTP_NOT_FOUND, response.getResponseCode());

            //put a value
            request = createSetPreferenceRequest(location, "Name", "Frodo");
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("2." + location, HttpURLConnection.HTTP_NO_CONTENT, response.getResponseCode());

            //now doing a get should succeed
            request = new GetMethodWebRequest(location);
            setAuthentication(request);
            response = webConversation.getResource(request);
            assertEquals("3." + location, HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject result = new JSONObject(response.getText());
            assertEquals("4." + location, "Frodo", result.optString("Name"));
        }
    }

    private WebRequest createSetPreferenceRequest(String location, String key, String value)
            throws UnsupportedEncodingException {
        String body = "key=" + URLEncoder.encode(key, "UTF-8") + "&value=" + URLEncoder.encode(value, "UTF-8");
        return new PutMethodWebRequest(location, new ByteArrayInputStream(body.getBytes()),
                "application/x-www-form-urlencoded");
    }

    /**
     * Create locations of preference HTTP resources corresponding to our test user, workspace, and project.
     */
    private List<String> getTestPreferenceNodes() {
        IPath projectPath = new Path(testProjectBaseLocation);
        String userId = getTestUserId();
        String workspaceId = projectPath.segment(0);
        String projectName = projectPath.segment(1);
        String userPref = toAbsoluteURI("prefs/user/" + userId + "/testprefs");
        String workspacePref = toAbsoluteURI("prefs/workspace/" + workspaceId + "/testprefs");
        String projectPref = toAbsoluteURI("prefs/project/" + workspaceId + '/' + projectName + "/testprefs");
        return Arrays.asList(userPref, workspacePref, projectPref);
    }

    /**
     * Returns preference nodes the client should not have access to.
     */
    private List<String> getIllegalPreferenceNodes() {
        return Arrays.asList(toAbsoluteURI("prefs/Users"), toAbsoluteURI("prefs/Workspaces"),
                toAbsoluteURI("prefs/Projects"));
    }
}