blob: a8ca659a875c4c2c329ce9df671f86cb63b86fca [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.googlesource.gerrit.plugins.its.base.workflow.action;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.server.config.SitePath;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
import com.googlesource.gerrit.plugins.its.base.workflow.ActionRequest;
import com.googlesource.gerrit.plugins.its.base.workflow.Property;
import com.googlesource.gerrit.plugins.its.base.workflow.action.AddVelocityComment.VelocityAdapterItsFacade;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.RuntimeInstance;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.eclipse.jgit.util.FileUtils;
public class AddVelocityCommentTest extends LoggingMockingTestCase {
private Injector injector;
private Path sitePath;
private ItsFacade its;
private RuntimeInstance velocityRuntime;
private boolean cleanupSitePath;
public void testWarnNoTemplateNameGiven() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
assertLogMessageContains("No template name");
}
public void testInlinePlain() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-text"});
IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-text");
expect(
velocityRuntime.evaluate(
(VelocityContext) anyObject(),
(Writer) anyObject(),
(String) anyObject(),
eq("Simple-text")))
.andAnswer(answer);
its.addComment("4711", "Simple-text");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
}
public void testInlineWithMultipleParameters() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Param2", "Param3"});
Set<Property> properties = Sets.newHashSet();
IAnswer<Boolean> answer = new VelocityWriterFiller("Param2 Param3");
expect(
velocityRuntime.evaluate(
(VelocityContext) anyObject(),
(Writer) anyObject(),
(String) anyObject(),
eq("Param2 Param3")))
.andAnswer(answer);
its.addComment("4711", "Param2 Param3");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, properties);
}
public void testInlineWithSingleProperty() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "${subject}"});
Set<Property> properties = Sets.newHashSet();
Property propertySubject = createMock(Property.class);
expect(propertySubject.getKey()).andReturn("subject").anyTimes();
expect(propertySubject.getValue()).andReturn("Rosebud").anyTimes();
properties.add(propertySubject);
IAnswer<Boolean> answer = new VelocityWriterFiller("Rosebud");
Capture<VelocityContext> contextCapture = createCapture();
expect(
velocityRuntime.evaluate(
capture(contextCapture),
(Writer) anyObject(),
(String) anyObject(),
eq("${subject}")))
.andAnswer(answer);
its.addComment("4711", "Rosebud");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, properties);
VelocityContext context = contextCapture.getValue();
assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
}
public void testInlineWithUnusedProperty() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Test"});
Set<Property> properties = Sets.newHashSet();
Property propertySubject = createMock(Property.class);
expect(propertySubject.getKey()).andReturn("subject").anyTimes();
expect(propertySubject.getValue()).andReturn("Rosebud").anyTimes();
properties.add(propertySubject);
IAnswer<Boolean> answer = new VelocityWriterFiller("Test");
expect(
velocityRuntime.evaluate(
(VelocityContext) anyObject(),
(Writer) anyObject(),
(String) anyObject(),
eq("Test")))
.andAnswer(answer);
its.addComment("4711", "Test");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, properties);
}
public void testInlineWithMultipleProperties() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters())
.andReturn(new String[] {"inline", "${subject}", "${reason}", "${subject}"});
Set<Property> properties = Sets.newHashSet();
Property propertySubject = createMock(Property.class);
expect(propertySubject.getKey()).andReturn("subject").anyTimes();
expect(propertySubject.getValue()).andReturn("Rosebud").anyTimes();
properties.add(propertySubject);
Property propertyReason = createMock(Property.class);
expect(propertyReason.getKey()).andReturn("reason").anyTimes();
expect(propertyReason.getValue()).andReturn("Life").anyTimes();
properties.add(propertyReason);
IAnswer<Boolean> answer = new VelocityWriterFiller("Rosebud Life Rosebud");
Capture<VelocityContext> contextCapture = createCapture();
expect(
velocityRuntime.evaluate(
capture(contextCapture),
(Writer) anyObject(),
(String) anyObject(),
eq("${subject} ${reason} ${subject}")))
.andAnswer(answer);
its.addComment("4711", "Rosebud Life Rosebud");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, properties);
VelocityContext context = contextCapture.getValue();
assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
assertEquals("Reason property of context did not match", "Life", context.get("reason"));
}
public void testItsWrapperFormatLink1Parameter()
throws IOException, SecurityException, IllegalArgumentException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-Text"});
IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-Text");
Capture<VelocityContext> contextCapture = createCapture();
expect(
velocityRuntime.evaluate(
capture(contextCapture),
(Writer) anyObject(),
(String) anyObject(),
eq("Simple-Text")))
.andAnswer(answer);
its.addComment("4711", "Simple-Text");
expect(its.createLinkForWebui("http://www.example.org/", "http://www.example.org/"))
.andReturn("Formatted Link");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
VelocityContext context = contextCapture.getValue();
Object itsAdapterObj = context.get("its");
assertNotNull("its property is null", itsAdapterObj);
assertTrue(
"Its is not a VelocityAdapterItsFacade instance",
itsAdapterObj instanceof VelocityAdapterItsFacade);
VelocityAdapterItsFacade itsAdapter = (VelocityAdapterItsFacade) itsAdapterObj;
String formattedLink = itsAdapter.formatLink("http://www.example.org/");
assertEquals("Result of formatLink does not match", "Formatted Link", formattedLink);
}
public void testItsWrapperFormatLink2Parameters()
throws IOException, SecurityException, IllegalArgumentException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("inline");
expect(actionRequest.getParameters()).andReturn(new String[] {"inline", "Simple-Text"});
IAnswer<Boolean> answer = new VelocityWriterFiller("Simple-Text");
Capture<VelocityContext> contextCapture = createCapture();
expect(
velocityRuntime.evaluate(
capture(contextCapture),
(Writer) anyObject(),
(String) anyObject(),
eq("Simple-Text")))
.andAnswer(answer);
its.addComment("4711", "Simple-Text");
expect(its.createLinkForWebui("http://www.example.org/", "Caption"))
.andReturn("Formatted Link");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
VelocityContext context = contextCapture.getValue();
Object itsAdapterObj = context.get("its");
assertNotNull("its property is null", itsAdapterObj);
assertTrue(
"Its is not a VelocityAdapterItsFacade instance",
itsAdapterObj instanceof VelocityAdapterItsFacade);
VelocityAdapterItsFacade itsAdapter = (VelocityAdapterItsFacade) itsAdapterObj;
String formattedLink = itsAdapter.formatLink("http://www.example.org/", "Caption");
assertEquals("Result of formatLink does not match", "Formatted Link", formattedLink);
}
public void testWarnTemplateNotFound() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("non-existing-template");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
assertLogMessageContains("non-existing-template");
}
public void testTemplateSimple() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("test-template");
injectTestTemplate("Simple Test Template");
IAnswer<Boolean> answer = new VelocityWriterFiller("Simple Test Template");
expect(
velocityRuntime.evaluate(
(VelocityContext) anyObject(),
(Writer) anyObject(),
(String) anyObject(),
eq("Simple Test Template")))
.andAnswer(answer);
its.addComment("4711", "Simple Test Template");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, new HashSet<Property>());
}
public void testTemplateMultipleParametersAndProperties() throws IOException {
ActionRequest actionRequest = createMock(ActionRequest.class);
expect(actionRequest.getParameter(1)).andReturn("test-template");
Set<Property> properties = Sets.newHashSet();
Property propertySubject = createMock(Property.class);
expect(propertySubject.getKey()).andReturn("subject").anyTimes();
expect(propertySubject.getValue()).andReturn("Rosebud").anyTimes();
properties.add(propertySubject);
Property propertyReason = createMock(Property.class);
expect(propertyReason.getKey()).andReturn("reason").anyTimes();
expect(propertyReason.getValue()).andReturn("Life").anyTimes();
properties.add(propertyReason);
injectTestTemplate(
"Test Template with subject: ${subject}.\n" + "${reason} is the reason for ${subject}.");
IAnswer<Boolean> answer =
new VelocityWriterFiller(
"Test Template with subject: Rosebud.\n" + "Life is the reason for Rosebud.");
Capture<VelocityContext> contextCapture = createCapture();
expect(
velocityRuntime.evaluate(
capture(contextCapture),
(Writer) anyObject(),
(String) anyObject(),
eq(
"Test Template with subject: ${subject}.\n"
+ "${reason} is the reason for ${subject}.")))
.andAnswer(answer);
its.addComment(
"4711", "Test Template with subject: Rosebud.\n" + "Life is the reason for Rosebud.");
replayMocks();
AddVelocityComment addVelocityComment = createAddVelocityComment();
addVelocityComment.execute("4711", actionRequest, properties);
VelocityContext context = contextCapture.getValue();
assertEquals("Subject property of context did not match", "Rosebud", context.get("subject"));
assertEquals("Reason property of context did not match", "Life", context.get("reason"));
}
private AddVelocityComment createAddVelocityComment() {
return injector.getInstance(AddVelocityComment.class);
}
private void injectTestTemplate(String template) throws IOException {
File templateParentFile =
new File(
sitePath.toFile(), "etc" + File.separatorChar + "its" + File.separator + "templates");
assertTrue(
"Failed to create parent (" + templateParentFile + ") for " + "rule base",
templateParentFile.mkdirs());
File templateFile = new File(templateParentFile, "test-template.vm");
try (FileWriter unbufferedWriter = new FileWriter(templateFile);
BufferedWriter writer = new BufferedWriter(unbufferedWriter)) {
writer.write(template);
}
}
@Override
public void setUp() throws Exception {
super.setUp();
cleanupSitePath = false;
injector = Guice.createInjector(new TestModule());
}
@Override
public void tearDown() throws Exception {
if (cleanupSitePath) {
if (Files.exists(sitePath)) {
FileUtils.delete(sitePath.toFile(), FileUtils.RECURSIVE);
}
}
super.tearDown();
}
private Path randomTargetPath() {
return Paths.get("target", "random-name-" + UUID.randomUUID().toString());
}
private class TestModule extends FactoryModule {
@Override
protected void configure() {
sitePath = randomTargetPath();
assertFalse("sitePath already (" + sitePath + ") already exists", Files.exists(sitePath));
cleanupSitePath = true;
bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
its = createMock(ItsFacade.class);
bind(ItsFacade.class).toInstance(its);
velocityRuntime = createMock(RuntimeInstance.class);
bind(RuntimeInstance.class).toInstance(velocityRuntime);
}
}
private class VelocityWriterFiller implements IAnswer<Boolean> {
private final String fill;
private final boolean returnValue;
private VelocityWriterFiller(String fill, boolean returnValue) {
this.fill = fill;
this.returnValue = returnValue;
}
private VelocityWriterFiller(String fill) {
this(fill, true);
}
@Override
public Boolean answer() throws Throwable {
Object[] arguments = EasyMock.getCurrentArguments();
Writer writer = (Writer) arguments[1];
writer.write(fill);
return returnValue;
}
}
}