blob: 429989618ca8518cda1f62540eb19f2523fac0e2 [file] [log] [blame]
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.edit;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.cloneProject;
import static com.google.gerrit.acceptance.GitUtil.createProject;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.apache.http.HttpStatus.SC_CONFLICT;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import static org.apache.http.HttpStatus.SC_NO_CONTENT;
import static org.apache.http.HttpStatus.SC_OK;
import static org.junit.Assert.fail;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.EditInfo;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.ChangeEdits.EditMessage;
import com.google.gerrit.server.change.ChangeEdits.Post;
import com.google.gerrit.server.change.ChangeEdits.Put;
import com.google.gerrit.server.change.FileContentUtil;
import com.google.gerrit.server.edit.ChangeEdit;
import com.google.gerrit.server.edit.ChangeEditModifier;
import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.edit.UnchangedCommitMessageException;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gson.stream.JsonReader;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import org.apache.commons.codec.binary.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeUtils.MillisProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
public class ChangeEditIT extends AbstractDaemonTest {
private static final String FILE_NAME = "foo";
private static final String FILE_NAME2 = "foo2";
private static final String FILE_NAME3 = "foo3";
private static final byte[] CONTENT_OLD = "bar".getBytes(UTF_8);
private static final byte[] CONTENT_NEW = "baz".getBytes(UTF_8);
private static final String CONTENT_NEW2_STR = "quxÄÜÖßµ";
private static final byte[] CONTENT_NEW2 = CONTENT_NEW2_STR.getBytes(UTF_8);
@Inject
private SchemaFactory<ReviewDb> reviewDbProvider;
@Inject
ChangeEditUtil editUtil;
@Inject
private ChangeEditModifier modifier;
@Inject
private FileContentUtil fileUtil;
private Change change;
private String changeId;
private Change change2;
private String changeId2;
private PatchSet ps;
private PatchSet ps2;
@Before
public void setUp() throws Exception {
db = reviewDbProvider.open();
changeId = newChange(git, admin.getIdent());
ps = getCurrentPatchSet(changeId);
amendChange(git, admin.getIdent(), changeId);
change = getChange(changeId);
assertThat(ps).isNotNull();
changeId2 = newChange2(git, admin.getIdent());
change2 = getChange(changeId2);
assertThat(change2).isNotNull();
ps2 = getCurrentPatchSet(changeId2);
assertThat(ps2).isNotNull();
final long clockStepMs = MILLISECONDS.convert(1, SECONDS);
final AtomicLong clockMs = new AtomicLong(
new DateTime(2009, 9, 30, 17, 0, 0).getMillis());
DateTimeUtils.setCurrentMillisProvider(new MillisProvider() {
@Override
public long getMillis() {
return clockMs.getAndAdd(clockStepMs);
}
});
}
@After
public void cleanup() {
DateTimeUtils.setCurrentMillisSystem();
db.close();
}
@Test
public void deleteEdit() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
editUtil.delete(editUtil.byChange(change).get());
assertThat(editUtil.byChange(change).isPresent()).isFalse();
}
@Test
public void publishEdit() throws Exception {
assertThat(modifier.createEdit(change, getCurrentPatchSet(changeId)))
.isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW2))).isEqualTo(RefUpdate.Result.FORCED);
editUtil.publish(editUtil.byChange(change).get());
assertThat(editUtil.byChange(change).isPresent()).isFalse();
}
@Test
public void publishEditRest() throws Exception {
PatchSet oldCurrentPatchSet = getCurrentPatchSet(changeId);
assertThat(modifier.createEdit(change, oldCurrentPatchSet)).isEqualTo(
RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
Optional<ChangeEdit> edit = editUtil.byChange(change);
RestResponse r = adminSession.post(urlPublish());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
edit = editUtil.byChange(change);
assertThat(edit.isPresent()).isFalse();
PatchSet newCurrentPatchSet = getCurrentPatchSet(changeId);
assertThat(newCurrentPatchSet.getId()).isNotEqualTo(oldCurrentPatchSet.getId());
}
@Test
public void deleteEditRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
Optional<ChangeEdit> edit = editUtil.byChange(change);
RestResponse r = adminSession.delete(urlEdit());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
edit = editUtil.byChange(change);
assertThat(edit.isPresent()).isFalse();
}
@Test
public void publishEditRestWithoutCLA() throws Exception {
setUseContributorAgreements(InheritableBoolean.TRUE);
PatchSet oldCurrentPatchSet = getCurrentPatchSet(changeId);
assertThat(modifier.createEdit(change, oldCurrentPatchSet)).isEqualTo(
RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
RestResponse r = adminSession.post(urlPublish());
assertThat(r.getStatusCode()).isEqualTo(SC_FORBIDDEN);
setUseContributorAgreements(InheritableBoolean.FALSE);
r = adminSession.post(urlPublish());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
}
@Test
public void rebaseEdit() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
ChangeEdit edit = editUtil.byChange(change).get();
PatchSet current = getCurrentPatchSet(changeId);
assertThat(edit.getBasePatchSet().getPatchSetId()).isEqualTo(
current.getPatchSetId() - 1);
Date beforeRebase = edit.getEditCommit().getCommitterIdent().getWhen();
modifier.rebaseEdit(edit, current);
edit = editUtil.byChange(change).get();
assertByteArray(fileUtil.getContent(projectCache.get(edit.getChange().getProject()),
ObjectId.fromString(edit.getRevision().get()), FILE_NAME), CONTENT_NEW);
assertByteArray(fileUtil.getContent(projectCache.get(edit.getChange().getProject()),
ObjectId.fromString(edit.getRevision().get()), FILE_NAME2), CONTENT_NEW2);
assertThat(edit.getBasePatchSet().getPatchSetId()).isEqualTo(
current.getPatchSetId());
Date afterRebase = edit.getEditCommit().getCommitterIdent().getWhen();
assertThat(beforeRebase.equals(afterRebase)).isFalse();
}
@Test
public void rebaseEditRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
ChangeEdit edit = editUtil.byChange(change).get();
PatchSet current = getCurrentPatchSet(changeId);
assertThat(edit.getBasePatchSet().getPatchSetId()).isEqualTo(
current.getPatchSetId() - 1);
Date beforeRebase = edit.getEditCommit().getCommitterIdent().getWhen();
RestResponse r = adminSession.post(urlRebase());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
edit = editUtil.byChange(change).get();
assertByteArray(fileUtil.getContent(projectCache.get(edit.getChange().getProject()),
ObjectId.fromString(edit.getRevision().get()), FILE_NAME), CONTENT_NEW);
assertByteArray(fileUtil.getContent(projectCache.get(edit.getChange().getProject()),
ObjectId.fromString(edit.getRevision().get()), FILE_NAME2), CONTENT_NEW2);
assertThat(edit.getBasePatchSet().getPatchSetId()).isEqualTo(
current.getPatchSetId());
Date afterRebase = edit.getEditCommit().getCommitterIdent().getWhen();
assertThat(afterRebase).isNotEqualTo(beforeRebase);
}
@Test
public void rebaseEditWithConflictsRest_Conflict() throws Exception {
PatchSet current = getCurrentPatchSet(changeId2);
assertThat(modifier.createEdit(change2, current)).isEqualTo(RefUpdate.Result.NEW);
assertThat(
modifier.modifyFile(editUtil.byChange(change2).get(), FILE_NAME,
RestSession.newRawInput(CONTENT_NEW))).isEqualTo(RefUpdate.Result.FORCED);
ChangeEdit edit = editUtil.byChange(change2).get();
assertThat(edit.getBasePatchSet().getPatchSetId()).isEqualTo(
current.getPatchSetId());
PushOneCommit push =
pushFactory.create(db, admin.getIdent(), PushOneCommit.SUBJECT, FILE_NAME,
new String(CONTENT_NEW2), changeId2);
push.to(git, "refs/for/master").assertOkStatus();
RestResponse r = adminSession.post(urlRebase());
assertThat(r.getStatusCode()).isEqualTo(SC_CONFLICT);
}
@Test
public void updateExistingFile() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW);
editUtil.delete(edit.get());
edit = editUtil.byChange(change);
assertThat(edit.isPresent()).isFalse();
}
@Test
public void updateRootCommitMessage() throws Exception {
createProject(sshSession, "root-msg-test", null, false);
git = cloneProject(sshSession.getUrl() + "/root-msg-test");
changeId = newChange(git, admin.getIdent());
change = getChange(changeId);
assertThat(modifier.createEdit(change, getCurrentPatchSet(changeId)))
.isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(edit.get().getEditCommit().getParentCount()).isEqualTo(0);
String msg = String.format("New commit message\n\nChange-Id: %s\n",
change.getKey());
assertThat(modifier.modifyMessage(edit.get(), msg))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertThat(edit.get().getEditCommit().getFullMessage()).isEqualTo(msg);
}
@Test
public void updateMessage() throws Exception {
assertThat(modifier.createEdit(change, getCurrentPatchSet(changeId)))
.isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertUnchangedMessage(edit, edit.get().getEditCommit().getFullMessage());
assertUnchangedMessage(edit, edit.get().getEditCommit().getFullMessage() + "\n\n");
String msg = String.format("New commit message\n\nChange-Id: %s\n",
change.getKey());
assertThat(modifier.modifyMessage(edit.get(), msg)).isEqualTo(
RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertThat(edit.get().getEditCommit().getFullMessage()).isEqualTo(msg);
editUtil.publish(edit.get());
assertThat(editUtil.byChange(change).isPresent()).isFalse();
ChangeInfo info = get(changeId, ListChangesOption.CURRENT_COMMIT,
ListChangesOption.CURRENT_REVISION);
assertThat(info.revisions.get(info.currentRevision).commit.message)
.isEqualTo(msg);
}
@Test
public void updateMessageRest() throws Exception {
assertThat(adminSession.get(urlEditMessage()).getStatusCode())
.isEqualTo(SC_NOT_FOUND);
EditMessage.Input in = new EditMessage.Input();
in.message = String.format("New commit message\n\n" +
CONTENT_NEW2_STR + "\n\nChange-Id: %s\n",
change.getKey());
assertThat(adminSession.put(urlEditMessage(), in).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
RestResponse r = adminSession.getJsonAccept(urlEditMessage());
assertThat(r.getStatusCode()).isEqualTo(SC_OK);
assertThat(readContentFromJson(r)).isEqualTo(in.message);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(edit.get().getEditCommit().getFullMessage())
.isEqualTo(in.message);
in.message = String.format("New commit message2\n\nChange-Id: %s\n",
change.getKey());
assertThat(adminSession.put(urlEditMessage(), in).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
edit = editUtil.byChange(change);
assertThat(edit.get().getEditCommit().getFullMessage())
.isEqualTo(in.message);
}
@Test
public void retrieveEdit() throws Exception {
RestResponse r = adminSession.get(urlEdit());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
EditInfo info = toEditInfo(false);
assertThat(info.commit.commit).isEqualTo(edit.get().getRevision().get());
assertThat(info.commit.parents).hasSize(1);
edit = editUtil.byChange(change);
editUtil.delete(edit.get());
r = adminSession.get(urlEdit());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
}
@Test
public void retrieveFilesInEdit() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
EditInfo info = toEditInfo(true);
assertThat(info.files).hasSize(2);
List<String> l = Lists.newArrayList(info.files.keySet());
assertThat(l.get(0)).isEqualTo("/COMMIT_MSG");
assertThat(l.get(1)).isEqualTo("foo");
}
@Test
public void deleteExistingFile() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.deleteFile(edit.get(), FILE_NAME)).isEqualTo(
RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
}
@Test
public void renameExistingFile() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.renameFile(edit.get(), FILE_NAME, FILE_NAME3))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME3), CONTENT_OLD);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
}
@Test
public void createEditByDeletingExistingFileRest() throws Exception {
RestResponse r = adminSession.delete(urlEditFile());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
}
@Test
public void deletingNonExistingEditRest() throws Exception {
RestResponse r = adminSession.delete(urlEdit());
assertThat(r.getStatusCode()).isEqualTo(SC_NOT_FOUND);
}
@Test
public void deleteExistingFileRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(adminSession.delete(urlEditFile()).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
}
@Test
public void restoreDeletedFileInPatchSet() throws Exception {
assertThat(modifier.createEdit(change2, ps2)).isEqualTo(
RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change2);
assertThat(modifier.restoreFile(edit.get(), FILE_NAME)).isEqualTo(
RefUpdate.Result.FORCED);
edit = editUtil.byChange(change2);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_OLD);
}
@Test
public void renameFileRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Post.Input in = new Post.Input();
in.oldPath = FILE_NAME;
in.newPath = FILE_NAME3;
assertThat(adminSession.post(urlEdit(), in).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME3), CONTENT_OLD);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
}
@Test
public void restoreDeletedFileInPatchSetRest() throws Exception {
Post.Input in = new Post.Input();
in.restorePath = FILE_NAME;
assertThat(adminSession.post(urlEdit2(), in).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change2);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_OLD);
}
@Test
public void amendExistingFile() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW2)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW2);
}
@Test
public void createAndChangeEditInOneRequestRest() throws Exception {
Put.Input in = new Put.Input();
in.content = RestSession.newRawInput(CONTENT_NEW);
assertThat(adminSession.putRaw(urlEditFile(), in.content).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW);
in.content = RestSession.newRawInput(CONTENT_NEW2);
assertThat(adminSession.putRaw(urlEditFile(), in.content).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW2);
}
@Test
public void changeEditRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Put.Input in = new Put.Input();
in.content = RestSession.newRawInput(CONTENT_NEW);
assertThat(adminSession.putRaw(urlEditFile(), in.content).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_NEW);
}
@Test
public void emptyPutRequest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(adminSession.put(urlEditFile()).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), "".getBytes());
}
@Test
public void createEmptyEditRest() throws Exception {
assertThat(adminSession.post(urlEdit()).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME), CONTENT_OLD);
}
@Test
public void getFileContentRest() throws Exception {
Put.Input in = new Put.Input();
in.content = RestSession.newRawInput(CONTENT_NEW);
assertThat(adminSession.putRaw(urlEditFile(), in.content).getStatusCode())
.isEqualTo(SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME, RestSession.newRawInput(CONTENT_NEW2)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
RestResponse r = adminSession.getJsonAccept(urlEditFile());
assertThat(r.getStatusCode()).isEqualTo(SC_OK);
assertThat(readContentFromJson(r)).isEqualTo(
StringUtils.newStringUtf8(CONTENT_NEW2));
}
@Test
public void getFileNotFoundRest() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
assertThat(adminSession.delete(urlEditFile()).getStatusCode()).isEqualTo(
SC_NO_CONTENT);
Optional<ChangeEdit> edit = editUtil.byChange(change);
try {
fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME);
fail("ResourceNotFoundException expected");
} catch (ResourceNotFoundException rnfe) {
}
RestResponse r = adminSession.get(urlEditFile());
assertThat(r.getStatusCode()).isEqualTo(SC_NO_CONTENT);
}
@Test
public void addNewFile() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME2, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME2), CONTENT_NEW);
}
@Test
public void addNewFileAndAmend() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME2, RestSession.newRawInput(CONTENT_NEW)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME2), CONTENT_NEW);
assertThat(modifier.modifyFile(edit.get(), FILE_NAME2, RestSession.newRawInput(CONTENT_NEW2)))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()),
ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME2), CONTENT_NEW2);
}
@Test
public void writeNoChanges() throws Exception {
assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW);
try {
modifier.modifyFile(
editUtil.byChange(change).get(),
FILE_NAME,
RestSession.newRawInput(CONTENT_OLD));
fail();
} catch (InvalidChangeOperationException e) {
assertThat(e.getMessage()).isEqualTo("no changes were made");
}
}
@Test
public void editCommitMessageCopiesLabelScores() throws Exception {
String cr = "Code-Review";
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
cfg.getLabelSections().get(cr)
.setCopyAllScoresIfNoCodeChange(true);
saveProjectConfig(allProjects, cfg);
String changeId = change.getKey().get();
ReviewInput r = new ReviewInput();
r.labels = ImmutableMap.<String, Short> of(cr, (short) 1);
gApi.changes()
.id(changeId)
.revision(change.currentPatchSetId().get())
.review(r);
assertThat(modifier.createEdit(change, getCurrentPatchSet(changeId)))
.isEqualTo(RefUpdate.Result.NEW);
Optional<ChangeEdit> edit = editUtil.byChange(change);
String newSubj = "New commit message";
String newMsg = newSubj + "\n\nChange-Id: " + changeId + "\n";
assertThat(modifier.modifyMessage(edit.get(), newMsg))
.isEqualTo(RefUpdate.Result.FORCED);
edit = editUtil.byChange(change);
editUtil.publish(edit.get());
ChangeInfo info = get(changeId);
assertThat(info.subject).isEqualTo(newSubj);
List<ApprovalInfo> approvals = info.labels.get(cr).all;
assertThat(approvals).hasSize(1);
assertThat(approvals.get(0).value).isEqualTo(1);
}
private void assertUnchangedMessage(Optional<ChangeEdit> edit, String message)
throws Exception {
try {
modifier.modifyMessage(
edit.get(),
message);
fail("UnchangedCommitMessageException expected");
} catch (UnchangedCommitMessageException ex) {
assertThat(ex.getMessage()).isEqualTo(
"New commit message cannot be same as existing commit message");
}
}
private String newChange(Git git, PersonIdent ident) throws Exception {
PushOneCommit push =
pushFactory.create(db, ident, PushOneCommit.SUBJECT, FILE_NAME,
new String(CONTENT_OLD, StandardCharsets.UTF_8));
return push.to(git, "refs/for/master").getChangeId();
}
private String amendChange(Git git, PersonIdent ident, String changeId) throws Exception {
PushOneCommit push =
pushFactory.create(db, ident, PushOneCommit.SUBJECT, FILE_NAME2,
new String(CONTENT_NEW2, StandardCharsets.UTF_8), changeId);
return push.to(git, "refs/for/master").getChangeId();
}
private String newChange2(Git git, PersonIdent ident) throws Exception {
PushOneCommit push =
pushFactory.create(db, ident, PushOneCommit.SUBJECT, FILE_NAME,
new String(CONTENT_OLD, StandardCharsets.UTF_8));
return push.rm(git, "refs/for/master").getChangeId();
}
private Change getChange(String changeId) throws Exception {
return getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
}
private PatchSet getCurrentPatchSet(String changeId) throws Exception {
return db.patchSets()
.get(getChange(changeId).currentPatchSetId());
}
private static void assertByteArray(BinaryResult result, byte[] expected)
throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
result.writeTo(os);
assertThat(os.toByteArray()).isEqualTo(expected);
}
private String urlEdit() {
return "/changes/"
+ change.getChangeId()
+ "/edit";
}
private String urlEdit2() {
return "/changes/"
+ change2.getChangeId()
+ "/edit/";
}
private String urlEditMessage() {
return "/changes/"
+ change.getChangeId()
+ "/edit:message";
}
private String urlEditFile() {
return urlEdit()
+ "/"
+ FILE_NAME;
}
private String urlGetFiles() {
return urlEdit()
+ "?list";
}
private String urlPublish() {
return "/changes/"
+ change.getChangeId()
+ "/edit:publish";
}
private String urlRebase() {
return "/changes/"
+ change.getChangeId()
+ "/edit:rebase";
}
private EditInfo toEditInfo(boolean files) throws IOException {
RestResponse r = adminSession.get(files ? urlGetFiles() : urlEdit());
assertThat(r.getStatusCode()).isEqualTo(SC_OK);
return newGson().fromJson(r.getReader(), EditInfo.class);
}
private String readContentFromJson(RestResponse r) throws IOException {
JsonReader jsonReader = new JsonReader(r.getReader());
jsonReader.setLenient(true);
return newGson().fromJson(jsonReader, String.class);
}
}