org.eclipse.orion.server.tests.servlets.git.GitCommitTest.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.tests.servlets.git.GitCommitTest.java

Source

/*******************************************************************************
 * Copyright (c) 2011, 2012 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.servlets.git;

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

import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URI;

import org.eclipse.core.runtime.IPath;
import org.eclipse.orion.internal.server.core.IOUtilities;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.server.git.GitConstants;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Ignore;
import org.junit.Test;

import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.PostMethodWebRequest;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;

public class GitCommitTest extends GitTest {

    @Test
    public void testCommitOnly() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitStatusUri = gitSection.getString(GitConstants.KEY_STATUS);

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "change to commit");
        addFile(testTxt);

        JSONObject folder1 = getChild(project, "folder");
        JSONObject folderTxt = getChild(folder1, "folder.txt");
        modifyFile(folderTxt, "change to commit");
        addFile(folderTxt);

        assertStatus(new StatusResult().setChanged(2), gitStatusUri);

        // "git commit -m 'message' -- test.txt
        final String commitMessage = "message";
        JSONObject commit = commitFile(testTxt, commitMessage);

        // check if response contains most important parts and if commit
        // message is valid
        assertNotNull(commit.optString(ProtocolConstants.KEY_LOCATION, null));
        assertNotNull(commit.optString(ProtocolConstants.KEY_NAME, null));
        assertEquals(commitMessage, commit.getString(GitConstants.KEY_COMMIT_MESSAGE));

        // still in index, not committed
        assertStatus(new StatusResult().setChangedNames("folder/folder.txt"), gitStatusUri);
    }

    @Test
    public void testCommitNoComment() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "change to commit");

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);

        addFile(testTxt);

        // commit with a null message
        WebRequest request = getPostGitCommitRequest(gitHeadUri /* all */, null, false);
        WebResponse response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode());
    }

    @Test
    public void testCommitEmptyComment() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "change to commit");

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);

        addFile(testTxt);

        // commit with a null message
        WebRequest request = getPostGitCommitRequest(gitHeadUri /* all */, "", false);
        WebResponse response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode());
    }

    @Test
    public void testCommitAll() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "change to commit");

        JSONObject folder1 = getChild(project, "folder");
        JSONObject folderTxt = getChild(folder1, "folder.txt");
        modifyFile(folderTxt, "change to commit");

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);
        String gitStatusUri = gitSection.getString(GitConstants.KEY_STATUS);
        String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);

        // "git add ."
        WebRequest request = GitAddTest.getPutGitIndexRequest(gitIndexUri);
        WebResponse response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        assertStatus(new StatusResult().setChanged(2), gitStatusUri);

        // commit all
        request = getPostGitCommitRequest(gitHeadUri, "message", false);
        response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        // assert clean
        assertStatus(StatusResult.CLEAN, gitStatusUri);
    }

    @Test
    public void testCommitAmend() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "change to commit");

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);
        String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);

        // "git add ."
        WebRequest request = GitAddTest.getPutGitIndexRequest(gitIndexUri);
        WebResponse response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        // commit all
        request = getPostGitCommitRequest(gitHeadUri, "Comit massage", false); // typos
        response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        // amend last commit
        request = getPostGitCommitRequest(gitHeadUri, "Commit message", true);
        response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        JSONArray commitsArray = log(gitHeadUri);
        assertEquals(2, commitsArray.length());
        JSONObject commit = commitsArray.getJSONObject(0);
        assertEquals("Commit message", commit.get(GitConstants.KEY_COMMIT_MESSAGE));
        commit = commitsArray.getJSONObject(1);
        assertEquals("Initial commit", commit.get(GitConstants.KEY_COMMIT_MESSAGE));
    }

    @Test
    public void testCommitHeadContent() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());

        String projectName = getMethodName();
        JSONObject project = createProjectOrLink(workspaceLocation, projectName, gitDir.toString());

        JSONObject testTxt = getChild(project, "test.txt");
        modifyFile(testTxt, "in HEAD");

        JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);
        String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);

        addFile(testTxt);

        // commit all
        WebRequest request = getPostGitCommitRequest(gitHeadUri, "message", false);
        WebResponse response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

        JSONObject testTxtGitSection = testTxt.getJSONObject(GitConstants.KEY_GIT);
        String testTxtGitHeadUri = testTxtGitSection.getString(GitConstants.KEY_HEAD);
        request = getGetGitCommitRequest(testTxtGitHeadUri, true);
        response = webConversation.getResponse(request);
        assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
        assertEquals("in HEAD", response.getText());
    }

    @Test
    @Ignore("not yet implemented")
    public void testCommitContentBySha() {
        // TODO: implement
    }

    @Test
    public void testCommitAllInFolder() throws Exception {
        // see bug 349480
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);

            // get project metadata
            WebRequest request = getGetRequest(contentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject cloneFolder = new JSONObject(response.getText());

            String fileName = "folder2.txt";
            JSONObject folder = getChild(cloneFolder, "folder");
            request = getPostFilesRequest(folder.getString(ProtocolConstants.KEY_LOCATION),
                    getNewFileJSON(fileName).toString(), fileName);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode());

            JSONObject testTxt = getChild(cloneFolder, "test.txt");

            // drill down to 'folder'
            JSONObject folderGitSection = folder.getJSONObject(GitConstants.KEY_GIT);
            String folderGitStatusUri = folderGitSection.getString(GitConstants.KEY_STATUS);
            String folderGitCloneUri = folderGitSection.getString(GitConstants.KEY_CLONE);

            JSONObject folder2Txt = getChild(folder, "folder2.txt");
            JSONObject folderTxt = getChild(folder, "folder.txt");

            // git section for the new file
            JSONObject folder2TxtGitSection = folder2Txt.getJSONObject(GitConstants.KEY_GIT);
            String folder2TxtGitIndexUri = folder2TxtGitSection.getString(GitConstants.KEY_INDEX);
            String folder2TxtGitHeadUri = folder2TxtGitSection.getString(GitConstants.KEY_HEAD);

            // stage the new file
            request = GitAddTest.getPutGitIndexRequest(folder2TxtGitIndexUri);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // commit the new file
            request = getPostGitCommitRequest(folder2TxtGitHeadUri, "folder/folder2.txt added", false);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // check status - clean
            assertStatus(StatusResult.CLEAN, folderGitStatusUri);

            // modify all
            modifyFile(testTxt, "change");
            modifyFile(folderTxt, "change");
            modifyFile(folder2Txt, "change");

            // check status - modified=3
            assertStatus(new StatusResult().setModified(3), folderGitStatusUri);

            addFile(folderTxt);
            addFile(testTxt);

            // check status - modified=1, changed=2
            assertStatus(new StatusResult().setModified(1).setChanged(2), folderGitStatusUri);

            // commit all
            // XXX: using HEAD URI for folder will commit all files in the folder, regardless of index state
            // request = getPostGitCommitRequest(folderGitHeadUri, "test.txt and folder/folder.txt changed", false);
            // the UI should use HEAD URI for the clone/root to commit all staged files
            JSONObject clone = getCloneForGitResource(folder);
            String cloneFolderGitHeadUri = clone.getString(GitConstants.KEY_HEAD);

            request = getPostGitCommitRequest(cloneFolderGitHeadUri, "test.txt and folder/folder.txt changed",
                    false);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // check status - changed=1
            assertStatus(new StatusResult().setModifiedNames("folder/folder2.txt"), folderGitStatusUri);

            // check the last commit for the repo
            JSONArray commitsArray = log(cloneFolderGitHeadUri);
            assertEquals(3, commitsArray.length());

            JSONObject commit = commitsArray.getJSONObject(0);
            assertEquals("test.txt and folder/folder.txt changed", commit.get(GitConstants.KEY_COMMIT_MESSAGE));
            JSONArray diffs = commit.getJSONArray(GitConstants.KEY_COMMIT_DIFFS);
            assertEquals(2, diffs.length());
            String oldPath = diffs.getJSONObject(0).getString(GitConstants.KEY_COMMIT_DIFF_OLDPATH);
            assertTrue("folder/folder.txt".equals(oldPath) || "test.txt".equals(oldPath));
            oldPath = diffs.getJSONObject(1).getString(GitConstants.KEY_COMMIT_DIFF_OLDPATH);
            assertTrue("folder/folder.txt".equals(oldPath) || "test.txt".equals(oldPath));
        }
    }

    @Test
    public void testCommitWithCommiterOverwritten() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);

            // get project metadata
            WebRequest request = getGetRequest(contentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject project = new JSONObject(response.getText());
            JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);

            String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);
            String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);

            // "git add ."
            request = GitAddTest.getPutGitIndexRequest(gitIndexUri);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // commit all
            final String commiterName = "committer name";
            final String commiterEmail = "committer email";

            request = getPostGitCommitRequest(gitHeadUri, "Comit message", false, commiterName, commiterEmail, null,
                    null);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // log
            JSONArray commitsArray = log(gitHeadUri);
            assertEquals(2, commitsArray.length());

            JSONObject commit = commitsArray.getJSONObject(0);
            assertEquals(commiterName, commit.get(GitConstants.KEY_COMMITTER_NAME));
            assertEquals(commiterEmail, commit.get(GitConstants.KEY_COMMITTER_EMAIL));
        }
    }

    @Test
    public void testCommitWithAuthorOverwritten() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);

            // get project metadata
            WebRequest request = getGetRequest(contentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject project = new JSONObject(response.getText());
            JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);

            String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);
            String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);

            // "git add ."
            request = GitAddTest.getPutGitIndexRequest(gitIndexUri);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // commit all
            final String commiterName = "committer name";
            final String commiterEmail = "committer email";

            request = getPostGitCommitRequest(gitHeadUri, "Comit message", false, commiterName, commiterEmail, null,
                    null);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // log
            JSONArray commitsArray = log(gitHeadUri);
            assertEquals(2, commitsArray.length());

            JSONObject commit = commitsArray.getJSONObject(0);
            assertEquals(commiterName, commit.get(GitConstants.KEY_COMMITTER_NAME));
            assertEquals(commiterEmail, commit.get(GitConstants.KEY_COMMITTER_EMAIL));
        }
    }

    @Test
    public void testCommitterAndAuthorFallback() throws Exception {
        URI workspaceLocation = createWorkspace(getMethodName());
        IPath[] clonePaths = createTestProjects(workspaceLocation);

        for (IPath clonePath : clonePaths) {
            // clone a  repo
            String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);

            // get project metadata
            WebRequest request = getGetRequest(contentLocation);
            WebResponse response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
            JSONObject project = new JSONObject(response.getText());
            JSONObject gitSection = project.getJSONObject(GitConstants.KEY_GIT);

            String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);
            String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);
            String gitConfigUri = gitSection.getString(GitConstants.KEY_CONFIG);

            // set user.name and user.email
            final String name = "name";
            final String email = "email";
            final String defaultName = "default name";
            final String defaultEmail = "default email";
            request = GitConfigTest.getPostGitConfigRequest(gitConfigUri, "user.name", defaultName);
            response = webConversation.getResponse(request);
            assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode());
            request = GitConfigTest.getPostGitConfigRequest(gitConfigUri, "user.email", defaultEmail);
            response = webConversation.getResponse(request);
            assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode());

            // "git add ."
            request = GitAddTest.getPutGitIndexRequest(gitIndexUri);
            response = webConversation.getResponse(request);
            assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode());

            // commit - author and committer not specified
            request = getPostGitCommitRequest(gitHeadUri, "1", false, null, null, null, null);
            response = webConversation.getResponse(request);
            assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode());

            // log - expect default values
            JSONArray commitsArray = log(gitHeadUri);
            assertEquals(2, commitsArray.length());

            JSONObject commit = commitsArray.getJSONObject(0);
            assertEquals(defaultName, commit.get(GitConstants.KEY_COMMITTER_NAME));
            assertEquals(defaultEmail, commit.get(GitConstants.KEY_COMMITTER_EMAIL));
            assertEquals(defaultName, commit.get(GitConstants.KEY_AUTHOR_NAME));
            assertEquals(defaultEmail, commit.get(GitConstants.KEY_AUTHOR_EMAIL));

            // commit - only committer given
            request = getPostGitCommitRequest(gitHeadUri, "2", true, name, email, null, null);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // log - expect author is the same as committer
            commitsArray = log(gitHeadUri);
            assertEquals(2, commitsArray.length());

            commit = commitsArray.getJSONObject(0);
            assertEquals(name, commit.get(GitConstants.KEY_COMMITTER_NAME));
            assertEquals(email, commit.get(GitConstants.KEY_COMMITTER_EMAIL));
            assertEquals(name, commit.get(GitConstants.KEY_AUTHOR_NAME));
            assertEquals(email, commit.get(GitConstants.KEY_AUTHOR_EMAIL));

            // commit - only committer name given
            request = getPostGitCommitRequest(gitHeadUri, "3", true, name, null, null, null);
            response = webConversation.getResponse(request);
            assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());

            // log - expect author is the same as committer and their email is defaultEmail
            commitsArray = log(gitHeadUri);
            assertEquals(2, commitsArray.length());

            commit = commitsArray.getJSONObject(0);
            assertEquals(name, commit.get(GitConstants.KEY_COMMITTER_NAME));
            assertEquals(defaultEmail, commit.get(GitConstants.KEY_COMMITTER_EMAIL));
            assertEquals(name, commit.get(GitConstants.KEY_AUTHOR_NAME));
            assertEquals(defaultEmail, commit.get(GitConstants.KEY_AUTHOR_EMAIL));
        }
    }

    static WebRequest getPostGitCommitRequest(String location, String message, boolean amend, String committerName,
            String committerEmail, String authorName, String authorEmail)
            throws JSONException, UnsupportedEncodingException {
        String requestURI = toAbsoluteURI(location);
        JSONObject body = new JSONObject();
        body.put(GitConstants.KEY_COMMIT_MESSAGE, message);
        body.put(GitConstants.KEY_COMMIT_AMEND, Boolean.toString(amend));
        body.put(GitConstants.KEY_COMMITTER_NAME, committerName);
        body.put(GitConstants.KEY_COMMITTER_EMAIL, committerEmail);
        body.put(GitConstants.KEY_AUTHOR_NAME, authorName);
        body.put(GitConstants.KEY_AUTHOR_EMAIL, authorEmail);
        WebRequest request = new PostMethodWebRequest(requestURI, IOUtilities.toInputStream(body.toString()),
                "UTF-8");
        request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
        setAuthentication(request);
        return request;
    }

    static WebRequest getPostGitCommitRequest(String location, String message, boolean amend)
            throws JSONException, UnsupportedEncodingException {
        return getPostGitCommitRequest(location, message, amend, null, null, null, null);
    }

    static WebRequest getGetGitCommitRequest(String location, boolean body) {
        return getGetGitCommitRequest(location, body, null, null);
    }

    static WebRequest getGetGitCommitRequest(String location, boolean body, Integer page, Integer pageSize) {
        String requestURI = toAbsoluteURI(location);
        boolean firstParam = true;
        if (body) {
            if (firstParam) {
                requestURI += "?";
                firstParam = false;
            } else {
                requestURI += "&";
            }
            requestURI += "parts=body";
        }

        if (page != null) {
            if (firstParam) {
                requestURI += "?";
                firstParam = false;
            } else {
                requestURI += "&";
            }
            requestURI += "page=" + page.intValue();
        }

        if (pageSize != null) {
            if (firstParam) {
                requestURI += "?";
                firstParam = false;
            } else {
                requestURI += "&";
            }
            requestURI += "pageSize=" + pageSize.intValue();
        }

        WebRequest request = new GetMethodWebRequest(requestURI);
        request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
        setAuthentication(request);
        return request;
    }
}