blob: 21d1ce43315ff53a7b6966ad569b9adfdf474e52 [file] [log] [blame]
// Copyright (C) 2013 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.server.change;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.PatchLineCommentAccess;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.AccountInfo;
import com.google.gerrit.server.change.CommentInfo.Side;
import com.google.gwtorm.server.ListResultSet;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import junit.framework.TestCase;
import org.easymock.IAnswer;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class CommentsTest extends TestCase {
private Injector injector;
private RevisionResource revRes1;
private RevisionResource revRes2;
private PatchLineComment plc1;
private PatchLineComment plc2;
private PatchLineComment plc3;
@Override
protected void setUp() throws Exception {
@SuppressWarnings("unchecked")
final DynamicMap<RestView<CommentResource>> views =
createMock(DynamicMap.class);
final TypeLiteral<DynamicMap<RestView<CommentResource>>> viewsType =
new TypeLiteral<DynamicMap<RestView<CommentResource>>>() {};
final AccountInfo.Loader.Factory alf =
createMock(AccountInfo.Loader.Factory.class);
final ReviewDb db = createMock(ReviewDb.class);
AbstractModule mod = new AbstractModule() {
@Override
protected void configure() {
bind(viewsType).toInstance(views);
bind(AccountInfo.Loader.Factory.class).toInstance(alf);
bind(ReviewDb.class).toInstance(db);
}};
Account.Id account1 = new Account.Id(1);
Account.Id account2 = new Account.Id(2);
AccountInfo.Loader accountLoader = createMock(AccountInfo.Loader.class);
accountLoader.fill();
expectLastCall().anyTimes();
expect(accountLoader.get(account1))
.andReturn(new AccountInfo(account1)).anyTimes();
expect(accountLoader.get(account2))
.andReturn(new AccountInfo(account2)).anyTimes();
expect(alf.create(true)).andReturn(accountLoader).anyTimes();
replay(accountLoader, alf);
revRes1 = createMock(RevisionResource.class);
revRes2 = createMock(RevisionResource.class);
PatchLineCommentAccess plca = createMock(PatchLineCommentAccess.class);
expect(db.patchComments()).andReturn(plca).anyTimes();
Change.Id changeId = new Change.Id(123);
PatchSet.Id psId1 = new PatchSet.Id(changeId, 1);
PatchSet ps1 = new PatchSet(psId1);
expect(revRes1.getPatchSet()).andReturn(ps1).anyTimes();
PatchSet.Id psId2 = new PatchSet.Id(changeId, 2);
PatchSet ps2 = new PatchSet(psId2);
expect(revRes2.getPatchSet()).andReturn(ps2);
long timeBase = System.currentTimeMillis();
plc1 = newPatchLineComment(psId1, "Comment1", null,
"FileOne.txt", Side.REVISION, 1, account1, timeBase,
"First Comment");
plc2 = newPatchLineComment(psId1, "Comment2", "Comment1",
"FileOne.txt", Side.REVISION, 1, account2, timeBase + 1000,
"Reply to First Comment");
plc3 = newPatchLineComment(psId1, "Comment3", "Comment1",
"FileOne.txt", Side.PARENT, 1, account1, timeBase + 2000,
"First Parent Comment");
expect(plca.publishedByPatchSet(psId1))
.andAnswer(results(plc1, plc2, plc3)).anyTimes();
expect(plca.publishedByPatchSet(psId2))
.andAnswer(results()).anyTimes();
replay(db, revRes1, revRes2, plca);
injector = Guice.createInjector(mod);
}
public void testListComments() throws Exception {
// test ListComments for patch set 1
assertListComments(injector, revRes1, ImmutableMap.of(
"FileOne.txt", Lists.newArrayList(plc3, plc1, plc2)));
// test ListComments for patch set 2
assertListComments(injector, revRes2,
Collections.<String, ArrayList<PatchLineComment>>emptyMap());
}
public void testGetComment() throws Exception {
// test GetComment for existing comment
assertGetComment(injector, revRes1, plc1, plc1.getKey().get());
// test GetComment for non-existent comment
assertGetComment(injector, revRes1, null, "BadComment");
}
private static IAnswer<ResultSet<PatchLineComment>> results(
final PatchLineComment... comments) {
return new IAnswer<ResultSet<PatchLineComment>>() {
@Override
public ResultSet<PatchLineComment> answer() throws Throwable {
return new ListResultSet<PatchLineComment>(Lists.newArrayList(comments));
}};
}
private static void assertGetComment(Injector inj, RevisionResource res,
PatchLineComment expected, String uuid) throws Exception {
GetComment getComment = inj.getInstance(GetComment.class);
Comments comments = inj.getInstance(Comments.class);
try {
CommentResource commentRes = comments.parse(res, IdString.fromUrl(uuid));
if (expected == null) {
fail("Expected no comment");
}
CommentInfo actual = (CommentInfo) getComment.apply(commentRes);
assertComment(expected, actual);
} catch (ResourceNotFoundException e) {
if (expected != null) {
fail("Expected to find comment");
}
}
}
private static void assertListComments(Injector inj, RevisionResource res,
Map<String, ArrayList<PatchLineComment>> expected) throws Exception {
Comments comments = inj.getInstance(Comments.class);
RestReadView<RevisionResource> listView =
(RestReadView<RevisionResource>) comments.list();
@SuppressWarnings("unchecked")
Map<String, List<CommentInfo>> actual =
(Map<String, List<CommentInfo>>) listView.apply(res);
assertNotNull(actual);
assertEquals(expected.size(), actual.size());
assertEquals(expected.keySet(), actual.keySet());
for (String filename : expected.keySet()) {
List<PatchLineComment> expectedComments = expected.get(filename);
List<CommentInfo> actualComments = actual.get(filename);
assertNotNull(actualComments);
assertEquals(expectedComments.size(), actualComments.size());
for (int i = 0; i < expectedComments.size(); i++) {
assertComment(expectedComments.get(i), actualComments.get(i));
}
}
}
private static void assertComment(PatchLineComment plc, CommentInfo ci) {
assertEquals(plc.getKey().get(), ci.id);
assertEquals(plc.getParentUuid(), ci.inReplyTo);
assertEquals("gerritcodereview#comment", ci.kind);
assertEquals(plc.getMessage(), ci.message);
assertNotNull(ci.author);
assertEquals(plc.getAuthor(), ci.author._id);
assertEquals(plc.getLine(), (int) ci.line);
assertEquals(plc.getSide() == 0 ? Side.PARENT : Side.REVISION,
Objects.firstNonNull(ci.side, Side.REVISION));
assertEquals(plc.getWrittenOn(), ci.updated);
}
private static PatchLineComment newPatchLineComment(PatchSet.Id psId,
String uuid, String inReplyToUuid, String filename, Side side, int line,
Account.Id authorId, long millis, String message) {
Patch.Key p = new Patch.Key(psId, filename);
PatchLineComment.Key id = new PatchLineComment.Key(p, uuid);
PatchLineComment plc =
new PatchLineComment(id, line, authorId, inReplyToUuid);
plc.setMessage(message);
plc.setSide(side == CommentInfo.Side.PARENT ? (short) 0 : (short) 1);
plc.setStatus(Status.PUBLISHED);
plc.setWrittenOn(new Timestamp(millis));
return plc;
}
}