1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.macro.wikibridge

File DefaultWikiMacroTest.java

 

Code metrics

0
99
16
1
382
251
16
0.16
6.19
16
1

Classes

Class Line # Actions
DefaultWikiMacroTest 75 99 0% 16 1
0.9913043499.1%
 

Contributing tests

This file is covered by 7 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.internal.macro.wikibridge;
21   
22    import java.io.Reader;
23    import java.io.StringReader;
24    import java.io.Writer;
25    import java.util.Arrays;
26    import java.util.Collections;
27    import java.util.HashMap;
28    import java.util.List;
29    import java.util.Map;
30    import java.util.Properties;
31   
32    import javax.inject.Provider;
33    import javax.script.ScriptContext;
34   
35    import org.apache.velocity.VelocityContext;
36    import org.hamcrest.Description;
37    import org.jmock.Expectations;
38    import org.jmock.api.Action;
39    import org.jmock.api.Invocation;
40    import org.junit.Assert;
41    import org.junit.Before;
42    import org.junit.Test;
43    import org.xwiki.bridge.DocumentAccessBridge;
44    import org.xwiki.component.descriptor.DefaultComponentDescriptor;
45    import org.xwiki.context.Execution;
46    import org.xwiki.model.reference.DocumentReference;
47    import org.xwiki.model.reference.SpaceReference;
48    import org.xwiki.model.reference.WikiReference;
49    import org.xwiki.rendering.converter.Converter;
50    import org.xwiki.rendering.listener.reference.DocumentResourceReference;
51    import org.xwiki.rendering.macro.MacroId;
52    import org.xwiki.rendering.macro.descriptor.DefaultContentDescriptor;
53    import org.xwiki.rendering.macro.script.ScriptMockSetup;
54    import org.xwiki.rendering.macro.wikibridge.WikiMacroDescriptor;
55    import org.xwiki.rendering.macro.wikibridge.WikiMacroFactory;
56    import org.xwiki.rendering.macro.wikibridge.WikiMacroManager;
57    import org.xwiki.rendering.macro.wikibridge.WikiMacroParameterDescriptor;
58    import org.xwiki.rendering.macro.wikibridge.WikiMacroVisibility;
59    import org.xwiki.rendering.parser.Parser;
60    import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
61    import org.xwiki.rendering.syntax.Syntax;
62    import org.xwiki.rendering.wiki.WikiModel;
63    import org.xwiki.script.ScriptContextManager;
64    import org.xwiki.test.jmock.AbstractComponentTestCase;
65    import org.xwiki.velocity.VelocityEngine;
66    import org.xwiki.velocity.VelocityManager;
67    import org.xwiki.wiki.descriptor.WikiDescriptorManager;
68   
69    /**
70    * Unit tests for {@link DefaultWikiMacro}.
71    *
72    * @version $Id: 61326f4f5ce677326e769c9d41c1a42c5947638a $
73    * @since 2.2M1
74    */
 
75    public class DefaultWikiMacroTest extends AbstractComponentTestCase
76    {
77    /**
78    * Dummy document reference of the document which contains the wiki macro.
79    */
80    private DocumentReference wikiMacroDocumentReference;
81   
82    /**
83    * The {@link org.xwiki.rendering.macro.wikibridge.WikiMacroManager} component.
84    */
85    private WikiMacroManager wikiMacroManager;
86   
87    private WikiModel mockWikiModel;
88   
89    private WikiMacroFactory mockWikiMacroFactory;
90   
91    private WikiDescriptorManager mockWikiDescriptorManager;
92   
93    private Provider<DocumentReference> mockCurrentDocumentReferenceProvider;
94   
95    private Provider<DocumentReference> mockCurrentSpaceReferenceProvider;
96   
97    private Map<String, Object> xcontext;
98   
 
99  7 toggle @Override
100    @Before
101    public void setUp() throws Exception
102    {
103  7 super.setUp();
104   
105    // Script setup.
106  7 ScriptMockSetup scriptMockSetup = new ScriptMockSetup(getMockery(), getComponentManager());
107  7 final DocumentAccessBridge mockDocBridge = scriptMockSetup.bridge;
108  7 this.mockWikiModel = scriptMockSetup.wikiModel;
109   
110  7 this.wikiMacroDocumentReference = new DocumentReference("wiki", "space", "macroPage");
111  7 this.wikiMacroManager = getComponentManager().getInstance(WikiMacroManager.class);
112   
113    // Make sure the old XWiki Context is set up in the Execution Context since it's used in
114    // DefaultWikiMacro.execute().
115  7 this.xcontext = new HashMap<String, Object>();
116  7 Execution execution = getComponentManager().getInstance(Execution.class);
117  7 execution.getContext().setProperty("xwikicontext", this.xcontext);
118  7 ScriptContextManager scm = getComponentManager().getInstance(ScriptContextManager.class);
119  7 scm.getCurrentScriptContext().setAttribute("xcontext", this.xcontext, ScriptContext.ENGINE_SCOPE);
120   
121  7 getMockery().checking(new Expectations()
122    {
 
123  7 toggle {
124  7 allowing(mockWikiDescriptorManager).getCurrentWikiId();
125  7 will(returnValue("wiki"));
126  7 allowing(mockCurrentDocumentReferenceProvider).get();
127  7 will(returnValue(new DocumentReference("wiki", "space", "document")));
128  7 allowing(mockCurrentSpaceReferenceProvider).get();
129  7 will(returnValue(new SpaceReference("space", new WikiReference("wiki"))));
130  7 allowing(mockDocBridge).getCurrentUser();
131  7 will(returnValue("dummy"));
132  7 allowing(mockDocBridge).setCurrentUser(with(any(String.class)));
133  7 allowing(mockDocBridge).getCurrentUserReference();
134  7 will(returnValue(new DocumentReference("wiki", "XWiki", "dummy")));
135  7 allowing(mockWikiMacroFactory).isAllowed(with(any(DocumentReference.class)),
136    with(any(WikiMacroVisibility.class)));
137  7 will(returnValue(true));
138   
139    // This is the document containing the wiki macro that will be put in the context available in the macro
140    // Since we're not testing it here, it can be null.
141  7 allowing(mockDocBridge).getDocument(wikiMacroDocumentReference);
142  7 will(returnValue(null));
143    }
144    });
145    }
146   
 
147  7 toggle @Override
148    protected void registerComponents() throws Exception
149    {
150  7 super.registerComponents();
151   
152  7 this.mockWikiDescriptorManager = registerMockComponent(WikiDescriptorManager.class);
153  7 this.mockCurrentDocumentReferenceProvider = registerMockComponent(DocumentReference.TYPE_PROVIDER, "current");
154  7 this.mockCurrentSpaceReferenceProvider = registerMockComponent(SpaceReference.TYPE_PROVIDER, "current");
155   
156    // some tests fail because the lookup of this component fails (the implementation is defined in xwiki-core)
157  7 this.mockWikiMacroFactory = registerMockComponent(WikiMacroFactory.class);
158    }
159   
 
160  6 toggle private void registerWikiMacro(String macroId, String macroContent, Syntax syntax) throws Exception
161    {
162  6 List<WikiMacroParameterDescriptor> parameterDescriptors =
163    Arrays.asList(new WikiMacroParameterDescriptor("param1", "This is param1", true),
164    new WikiMacroParameterDescriptor("param2", "This is param2", true));
165  6 registerWikiMacro(macroId, macroContent, syntax, parameterDescriptors);
166    }
167   
 
168  8 toggle private void registerWikiMacro(String macroId, String macroContent, Syntax syntax,
169    List<WikiMacroParameterDescriptor> parameterDescriptors) throws Exception
170    {
171  8 WikiMacroDescriptor descriptor = new WikiMacroDescriptor(new MacroId(macroId), "Wiki Macro", "Description",
172    "Test", WikiMacroVisibility.GLOBAL, new DefaultContentDescriptor(false), parameterDescriptors);
173   
174  8 Parser parser = getComponentManager().getInstance(Parser.class, syntax.toIdString());
175   
176  8 DefaultWikiMacro wikiMacro = new DefaultWikiMacro(wikiMacroDocumentReference, null, true, descriptor,
177    parser.parse(new StringReader(macroContent)), syntax, getComponentManager());
178   
179  8 this.wikiMacroManager.registerWikiMacro(wikiMacroDocumentReference, wikiMacro);
180    }
181   
182    // Tests
183   
184    /**
185    * Test normal wiki macro execution.
186    */
 
187  1 toggle @Test
188    public void testExecute() throws Exception
189    {
190  1 registerWikiMacro("wikimacro1", "This is **bold**", Syntax.XWIKI_2_0);
191   
192  1 Converter converter = getComponentManager().getInstance(Converter.class);
193   
194  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
195  1 converter.convert(new StringReader("{{wikimacro1 param1=\"value1\" param2=\"value2\"/}}"), Syntax.XWIKI_2_0,
196    Syntax.XHTML_1_0, printer);
197   
198    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
199  1 Assert.assertEquals("<p>This is <strong>bold</strong></p>", printer.toString());
200   
201  1 Assert.assertFalse(this.xcontext.containsKey("macro"));
202    }
203   
204    /**
205    * When a wiki macro is used in inline mode and its code starts with a macro, that nested macro is made inline. In
206    * other words, the nested macro should not generate extra paragraph elements.
207    */
 
208  1 toggle @Test
209    public void testExecuteWhenInlineAndWithMacro() throws Exception
210    {
211  1 registerWikiMacro("wikimacro1", "This is **bold**", Syntax.XWIKI_2_0);
212  1 registerWikiMacro("wikimacro2", "{{wikimacro1 param1=\"v1\" param2=\"v2\"/}}", Syntax.XWIKI_2_0);
213   
214  1 Converter converter = getComponentManager().getInstance(Converter.class);
215   
216  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
217    // Note: We're putting the macro after the "Hello" text to force it as an inline macro.
218  1 converter.convert(new StringReader("Hello {{wikimacro2 param1=\"value1\" param2=\"value2\"/}}"),
219    Syntax.XWIKI_2_0, Syntax.XHTML_1_0, printer);
220   
221    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
222  1 Assert.assertEquals("<p>Hello This is <strong>bold</strong></p>", printer.toString());
223    }
224   
225    /**
226    * Check that macro used inside wiki macro are executed as part of the document.
227    */
 
228  1 toggle @Test
229    public void testExecuteWhenInnerMacro() throws Exception
230    {
231  1 registerWikiMacro("wikimacro1", "{{toc/}}", Syntax.XWIKI_2_0);
232   
233  1 getMockery().checking(new Expectations()
234    {
 
235  1 toggle {
236  1 DocumentResourceReference reference = new DocumentResourceReference(null);
237  1 reference.setAnchor("Hheading");
238  1 allowing(mockWikiModel).getDocumentViewURL(reference);
239  1 will(returnValue("url"));
240    }
241    });
242   
243  1 Converter converter = getComponentManager().getInstance(Converter.class);
244   
245  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
246  1 converter.convert(new StringReader("= heading\n\n{{wikimacro1 param1=\"value1\" param2=\"value2\"/}}"),
247    Syntax.XWIKI_2_0, Syntax.XHTML_1_0, printer);
248   
249    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
250  1 Assert.assertEquals(
251    "<h1 id=\"Hheading\"><span>heading</span></h1>"
252    + "<ul><li><span class=\"wikilink\"><a href=\"#Hheading\">heading</a></span></li></ul>",
253    printer.toString());
254    }
255   
256    /**
257    * Check that macro used inside wiki macro are executed with the right syntax.
258    */
 
259  1 toggle @Test
260    public void testExecuteWhenWithDifferentMacroSyntax() throws Exception
261    {
262  1 registerWikiMacro("wikimacro", "{{groovy}}println \"[[path:/some/path]]\"{{/groovy}}", Syntax.XWIKI_2_1);
263   
264  1 Converter converter = getComponentManager().getInstance(Converter.class);
265   
266  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
267  1 converter.convert(new StringReader("{{wikimacro param1=\"value1\" param2=\"value2\"/}}"), Syntax.XWIKI_2_0,
268    Syntax.XHTML_1_0, printer);
269   
270    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
271  1 Assert.assertEquals("<p><span class=\"wikiinternallink\"><a href=\"/some/path\">"
272    + "<span class=\"wikigeneratedlinkcontent\">/some/path</span></a></span></p>", printer.toString());
273    }
274   
275    /**
276    * A wiki macro can directly provide the list of blocks instead of having to render them to let
277    * {@link DefaultWikiMacro} re-parse it.
278    */
 
279  1 toggle @Test
280    public void testExecuteWhenWikiMacroDirectlyProvideTheResult() throws Exception
281    {
282  1 registerWikiMacro("wikimacrowithresult",
283    "{{groovy}}"
284    + "xcontext.macro.result = java.util.Collections.singletonList(new org.xwiki.rendering.block.WordBlock(xcontext.macro.params.param1));"
285    + "{{/groovy}}",
286    Syntax.XWIKI_2_0);
287   
288  1 Converter converter = getComponentManager().getInstance(Converter.class);
289   
290  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
291    // Note: We're putting the macro after the "Hello" text to force it as an inline macro.
292  1 converter.convert(new StringReader("Hello {{wikimacrowithresult param1=\"World\" param2=\"param2\"/}}"),
293    Syntax.XWIKI_2_0, Syntax.XHTML_1_0, printer);
294   
295    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
296  1 Assert.assertEquals("<p>Hello World</p>", printer.toString());
297    }
298   
299    /**
300    * Test default parameter value injection.
301    */
 
302  1 toggle @Test
303    public void testDefaultParameterValues() throws Exception
304    {
305    // Velocity Manager mock.
306  1 final VelocityManager mockVelocityManager = getMockery().mock(VelocityManager.class);
307  1 DefaultComponentDescriptor<VelocityManager> descriptorVM = new DefaultComponentDescriptor<VelocityManager>();
308  1 descriptorVM.setRole(VelocityManager.class);
309  1 getComponentManager().registerComponent(descriptorVM, mockVelocityManager);
310   
311    // Initialize velocity engine.
312  1 final VelocityEngine vEngine = getComponentManager().getInstance(VelocityEngine.class);
313  1 Properties properties = new Properties();
314  1 properties.setProperty("resource.loader", "file");
315  1 vEngine.initialize(properties);
316   
317    // Hack into velocity context.
318  1 Execution execution = getComponentManager().getInstance(Execution.class);
319  1 Map<?, ?> xwikiContext = (Map<?, ?>) execution.getContext().getProperty("xwikicontext");
320  1 final VelocityContext vContext = new VelocityContext();
321  1 vContext.put("xcontext", xwikiContext);
322   
323  1 getMockery().checking(new Expectations()
324    {
 
325  1 toggle {
326  1 oneOf(mockVelocityManager).getCurrentVelocityContext();
327  1 will(returnValue(vContext));
328  1 oneOf(mockVelocityManager).evaluate(with(any(Writer.class)), with(any(String.class)),
329    with(any(Reader.class)));
330  1 will(new Action()
331    {
 
332  1 toggle @Override
333    public Object invoke(Invocation invocation) throws Throwable
334    {
335  1 return vEngine.evaluate(vContext, (Writer) invocation.getParameter(0),
336    (String) invocation.getParameter(1), (Reader) invocation.getParameter(2));
337    }
338   
 
339  0 toggle @Override
340    public void describeTo(Description description)
341    {
342    }
343    });
344    }
345    });
346   
347  1 List<WikiMacroParameterDescriptor> parameterDescriptors =
348    Arrays.asList(new WikiMacroParameterDescriptor("param1", "This is param1", false, "default_value"));
349   
350  1 registerWikiMacro("wikimacro1", "{{velocity}}$xcontext.macro.params.param1{{/velocity}}", Syntax.XWIKI_2_0,
351    parameterDescriptors);
352   
353  1 Converter converter = getComponentManager().getInstance(Converter.class);
354   
355  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
356  1 converter.convert(new StringReader("{{wikimacro1/}}"), Syntax.XWIKI_2_0, Syntax.XHTML_1_0, printer);
357   
358    // Note: We're using XHTML as the output syntax just to make it easy for asserting.
359  1 Assert.assertEquals("<p>default_value</p>", printer.toString());
360    }
361   
 
362  1 toggle @Test
363    public void testGetCurrentMacroBlock() throws Exception
364    {
365  1 registerWikiMacro("wikimacro",
366    "{{groovy}}" + "println xcontext.macro.context.getCurrentMacroBlock().id\n"
367    + "println xcontext.macro.context.getCurrentMacroBlock().parent.class\n"
368    + "println xcontext.macro.context.getCurrentMacroBlock().nextSibling.children[0].word\n"
369    + "println xcontext.macro.context.getCurrentMacroBlock().previousSibling.children[0].word\n"
370    + "{{/groovy}}",
371    Syntax.XWIKI_2_0, Collections.<WikiMacroParameterDescriptor>emptyList());
372   
373  1 Converter converter = getComponentManager().getInstance(Converter.class);
374   
375  1 DefaultWikiPrinter printer = new DefaultWikiPrinter();
376  1 converter.convert(new StringReader("before\n\n{{wikimacro/}}\n\nafter"), Syntax.XWIKI_2_0, Syntax.PLAIN_1_0,
377    printer);
378   
379  1 Assert.assertEquals("before" + "\n\n" + "wikimacro\n" + "class org.xwiki.rendering.block.XDOM\n" + "after\n"
380    + "before" + "\n\n" + "after", printer.toString());
381    }
382    }