/******************************************************************************
* Copyright 2013 Bernhard Grünewaldt *
* *
* 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 ut.com.google.code.greenwood.confluenceadvancedcodeblockplugin;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.log4j.PropertyConfigurator;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.ini4j.InvalidFileFormatException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.atlassian.applinks.api.ApplicationLinkService;
import com.atlassian.confluence.content.render.xhtml.ConversionContext;
import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext;
import com.atlassian.confluence.core.ContentPropertyManager;
import com.atlassian.confluence.core.DefaultContentPropertyManager;
import com.atlassian.confluence.pages.Page;
import com.atlassian.confluence.pages.PageManager;
import com.atlassian.confluence.renderer.PageContext;
import com.atlassian.confluence.renderer.radeox.macros.MacroUtils;
import com.atlassian.confluence.setup.settings.Settings;
import com.atlassian.confluence.setup.settings.SettingsManager;
import com.atlassian.confluence.util.i18n.I18NBean;
import com.atlassian.confluence.util.i18n.I18NBeanFactory;
import com.atlassian.confluence.util.velocity.VelocityUtils;
import com.google.code.greenwood.confluenceadvancedcodeblockplugin.macro.AdvancedCodeBlockMacro;
import com.google.code.greenwood.confluenceadvancedcodeblockplugin.macro.BaseAdvancedCodeblockMacro;
@RunWith(PowerMockRunner.class)
@PrepareForTest({MacroUtils.class, VelocityUtils.class})
public class AdvancedCodeBlockMacroTest {
@Mock private ConversionContext conversionContext;
@Mock private I18NBean i18NBean;
@Mock private I18NBeanFactory i18NBeanFactory;
@Mock private ApplicationLinkService applicationLinkService;
@Mock private ContentPropertyManager contentPropertyManager;
@Mock private PageManager pageManager;
private Page page;
private static final Logger log = LoggerFactory.getLogger(AdvancedCodeBlockMacroTest.class);
private static final String configWithContent = "[config 1]\n"+
"foo=awesome\n"+
"\n"+
"[config 2]\n"+
"foo=great\n"+
"\n"+
"[content]\n"+
"my replacable ${foo} text <html>";
@Before
public void setup() throws Exception {
PropertyConfigurator.configure(this.getClass().getClassLoader().getResource("log4j.properties"));
log.debug("setUp()");
// Better mocks: https://bitbucket.org/atlassian/confluence-socialbookmarking-plugin/src/32a13cb027cb08c8063504ea05a50932daa99430/src/test/java/com/atlassian/confluence/plugins/socialbookmarking/BookmarkUpdateListenerTest.java
Settings settings = new Settings();
settings.setBaseUrl("http://foo.com");
this.page = new Page();
page.setTitle("hoge");
page.setId(4l);
SettingsManager settingManager = mock(SettingsManager.class);
when(settingManager.getGlobalSettings()).thenReturn(settings);
i18NBean = mock(I18NBean.class);
when(i18NBean.getText(anyString())).thenReturn("jirachart.macro.dialog.statistype.statuses");
i18NBeanFactory = mock(I18NBeanFactory.class);
when(i18NBeanFactory.getI18NBean()).thenReturn(i18NBean);
pageManager = mock(PageManager.class);
when(pageManager.getPage(anyInt())).thenReturn(this.page);
this.contentPropertyManager = new DefaultContentPropertyManager();
PageContext pageContext = mock(PageContext.class);
when(pageContext.getSpaceKey()).thenReturn("FOO");
conversionContext = new DefaultConversionContext(pageContext);
when(conversionContext.getEntity()).thenReturn(page);
}
//@Test
public void testExecute() throws Exception {
AdvancedCodeBlockMacro macro = new AdvancedCodeBlockMacro();
Map<String,String> params = new HashMap<String,String>();
params.put(AdvancedCodeBlockMacro.MACRO_PARAM_ID, "my code");
params.put(AdvancedCodeBlockMacro.MACRO_PARAM_ENABLEDDL, "true");
// params.put(AdvancedCodeBlockMacro.MACRO_PARAM_ENABLERAWDDL, "true");
params.put(AdvancedCodeBlockMacro.MACRO_PARAM_LANG, "xml");
String html = new AdvancedCodeBlockMacro() {
@Override
public Map<String, Object> getDefaultVelocityContext() {
return new HashMap<String, Object>();
}
@Override
public String renderTemplate(String templateName, Map<String, Object> context) {
try {
VelocityContext vcontext = new VelocityContext();
if (context != null) {
for (Map.Entry<String, Object> entry : context.entrySet()) {
vcontext.put(entry.getKey(), entry.getValue());
}
}
StringWriter writer = new StringWriter();
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
Template t = ve.getTemplate( templateName );
t.merge( vcontext, writer );
System.out.println("================");
System.out.println(writer.toString());
System.out.println("================");
return writer.toString();
} catch (Exception e) {
System.err.println(e.getMessage());
return "EXCEPTION";
}
}
}.execute(params, configWithContent, conversionContext);
// Expected Output Parsen
String output = getFileFromClasspathAsString("/ut/de/it2media/transformer/expectedoutput-1.html", "ISO-8859-1");
output = output.replaceAll("\\r\\n", "\n");
output = output.replaceAll("\\r", "\n");
html = html.replaceAll("\\r\\n", "\n");
html = html.replaceAll("\\r", "\n");
System.out.println(html);
assertEquals(output, html);
}
@Test
public void testParseConfigWithContent() throws InvalidFileFormatException, IOException {
AdvancedCodeBlockMacro macro = new AdvancedCodeBlockMacro();
Map<String, Object> context = new HashMap<String,Object>();
String[] splitted = BaseAdvancedCodeblockMacro.splitMacroBodyIntoContentAndConfig(configWithContent);
String configUnparsed = splitted[0];
String contentUnparsed = splitted[1];
List<Map<String, String>> codeblocks = macro.parseConfigWithContent(configUnparsed, contentUnparsed, "key", 1l, context, true);
assertEquals("\nmy replacable awesome text <html>", codeblocks.get(0).get(AdvancedCodeBlockMacro.VELOCITY_PLACEHOLDER_CODE).toString());
assertEquals("config 1", codeblocks.get(0).get(AdvancedCodeBlockMacro.VELOCITY_PLACEHOLDER_TITLE).toString());
assertEquals("\nmy replacable great text <html>", codeblocks.get(1).get(AdvancedCodeBlockMacro.VELOCITY_PLACEHOLDER_CODE).toString());
assertEquals("config 2", codeblocks.get(1).get(AdvancedCodeBlockMacro.VELOCITY_PLACEHOLDER_TITLE).toString());
}
@Test
public void testVelocityOutput() throws Exception {
AdvancedCodeBlockMacro macro = new AdvancedCodeBlockMacro();
VelocityContext context = new VelocityContext();
Map<String, Object> innercontext = new HashMap<String,Object>();
String[] splitted = BaseAdvancedCodeblockMacro.splitMacroBodyIntoContentAndConfig(configWithContent);
String configUnparsed = splitted[0];
String contentUnparsed = splitted[1];
context.put("codeblocks",macro.parseConfigWithContent(configUnparsed, contentUnparsed, "key", 1l, innercontext, true));
for (Entry<String,Object> entry : innercontext.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
StringWriter writer = new StringWriter();
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
Template t = ve.getTemplate( "templates/default.vm" );
t.merge( context, writer );
System.out.println(writer);
}
private String getFileFromClasspathAsString(String classPathFilePath, String encoding) throws IOException, URISyntaxException {
String output = "";
FileInputStream stream = new FileInputStream(new File(getClass().getResource(classPathFilePath).toURI()));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,fc.size());
output = Charset.forName(encoding).decode(bb).toString();
} finally {
stream.close();
}
return output;
}
}