1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.rendering.internal.macro

File DisplayMacroTest.java

 
testDisplayMacroShowsVelocityMacrosAreIsolated: Failed to lookup component [org.xwiki.test.rendering.velo...
testDisplayMacroWhenSectionSpecified: Failed to lookup default document displayer.
testDisplayMacroWhenDisplayingDocumentWithRelativeReferences: Failed to lookup default document displayer.
testDisplayMacroWhenInvalidSectionSpecified: expected:<[Cannot find section [unknown] in document [wik...
 

Code metrics

4
131
21
2
438
338
27
0.21
6.24
10.5
1.29

Classes

Class Line # Actions
DisplayMacroTest 73 131 0% 27 88
0.4358974443.6%
DisplayMacroTest.ExpectedRecursiveInclusionException 207 0 - 0 0
-1.0 -
 

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;
21   
22    import java.io.StringReader;
23    import java.io.StringWriter;
24    import java.util.Collections;
25    import java.util.HashMap;
26    import java.util.List;
27    import java.util.Map;
28   
29    import org.apache.commons.lang3.reflect.FieldUtils;
30    import org.hamcrest.collection.IsArray;
31    import org.jmock.Expectations;
32    import org.jmock.api.Invocation;
33    import org.jmock.lib.action.CustomAction;
34    import org.junit.Assert;
35    import org.junit.Test;
36    import org.xwiki.bridge.DocumentModelBridge;
37    import org.xwiki.context.Execution;
38    import org.xwiki.display.internal.DocumentDisplayer;
39    import org.xwiki.display.internal.DocumentDisplayerParameters;
40    import org.xwiki.model.EntityType;
41    import org.xwiki.model.reference.DocumentReference;
42    import org.xwiki.model.reference.EntityReference;
43    import org.xwiki.model.reference.EntityReferenceResolver;
44    import org.xwiki.rendering.block.Block;
45    import org.xwiki.rendering.block.MacroBlock;
46    import org.xwiki.rendering.block.MetaDataBlock;
47    import org.xwiki.rendering.block.XDOM;
48    import org.xwiki.rendering.internal.macro.display.DisplayMacro;
49    import org.xwiki.rendering.internal.transformation.macro.MacroTransformation;
50    import org.xwiki.rendering.listener.MetaData;
51    import org.xwiki.rendering.macro.Macro;
52    import org.xwiki.rendering.macro.MacroExecutionException;
53    import org.xwiki.rendering.macro.display.DisplayMacroParameters;
54    import org.xwiki.rendering.macro.script.ScriptMockSetup;
55    import org.xwiki.rendering.parser.Parser;
56    import org.xwiki.rendering.renderer.PrintRendererFactory;
57    import org.xwiki.rendering.syntax.Syntax;
58    import org.xwiki.rendering.transformation.MacroTransformationContext;
59    import org.xwiki.rendering.transformation.Transformation;
60    import org.xwiki.security.authorization.AuthorizationManager;
61    import org.xwiki.security.authorization.ContextualAuthorizationManager;
62    import org.xwiki.security.authorization.Right;
63    import org.xwiki.test.jmock.AbstractComponentTestCase;
64    import org.xwiki.velocity.VelocityManager;
65   
66    import static org.xwiki.rendering.test.BlockAssert.assertBlocks;
67   
68    /**
69    * Unit tests for {@link DisplayMacro}.
70    *
71    * @version $Id: 47c960c8e171a8fcdf192e64014179ac0898eb4c $
72    */
 
73    public class DisplayMacroTest extends AbstractComponentTestCase
74    {
75    private ScriptMockSetup mockSetup;
76   
77    private DisplayMacro displayMacro;
78   
79    private PrintRendererFactory rendererFactory;
80   
81    /**
82    * Mocks the component that is used to resolve the 'reference' parameter.
83    */
84    private EntityReferenceResolver<String> mockEntityReferenceResolver;
85   
86    private ContextualAuthorizationManager mockContextualAuthorization;
87   
88    private DocumentModelBridge mockDocument;
89   
 
90  7 toggle @Override
91    public void setUp() throws Exception
92    {
93  7 super.setUp();
94   
95    // Put a fake XWiki context on the execution context.
96  7 Execution execution = getComponentManager().getInstance(Execution.class);
97  7 execution.getContext().setProperty("xwikicontext", new HashMap<Object, Object>());
98    }
99   
 
100  7 toggle @Override
101    protected void registerComponents() throws Exception
102    {
103  7 super.registerComponents();
104   
105  7 this.mockSetup = new ScriptMockSetup(getMockery(), getComponentManager());
106   
107  7 this.mockEntityReferenceResolver =
108    registerMockComponent(EntityReferenceResolver.TYPE_STRING, "macro", "macroDocumentReferenceResolver");
109    // Make sure to not load the standard AuthorizationManager which trigger too many things
110  7 registerMockComponent(AuthorizationManager.class);
111   
112  7 this.mockContextualAuthorization = getComponentManager().getInstance(ContextualAuthorizationManager.class);
113  7 this.displayMacro = (DisplayMacro) getComponentManager().getInstance(Macro.class, "display");
114  7 this.rendererFactory = getComponentManager().getInstance(PrintRendererFactory.class, "event/1.0");
115    }
116   
 
117  0 toggle @Test
118    public void testDisplayMacroShowsVelocityMacrosAreIsolated() throws Exception
119    {
120    // @formatter:off
121  0 String expected =
122    "beginDocument\n"
123    + "beginMetaData [[base]=[wiki:Space.DisplayedPage][source]=[wiki:Space.DisplayedPage]"
124    + "[syntax]=[XWiki 2.0]]\n"
125    + "beginMacroMarkerStandalone [velocity] [] [#testmacro]\n"
126    + "beginParagraph\n"
127    + "onSpecialSymbol [#]\n"
128    + "onWord [testmacro]\n"
129    + "endParagraph\n"
130    + "endMacroMarkerStandalone [velocity] [] [#testmacro]\n"
131    + "endMetaData [[base]=[wiki:Space.DisplayedPage][source]=[wiki:Space.DisplayedPage]"
132    + "[syntax]=[XWiki 2.0]]\n"
133    + "endDocument";
134    // @formatter:on
135   
136    // We verify that a Velocity macro set in the including page is not seen in the displayed page.
137  0 List<Block> blocks =
138    Test failure here runDisplayMacroWithPreVelocity("#macro(testmacro)#end", "{{velocity}}#testmacro{{/velocity}}");
139   
140  0 assertBlocks(expected, blocks, this.rendererFactory);
141    }
142   
 
143  1 toggle @Test
144    public void testDisplayMacroWithNoDocumentSpecified() throws Exception
145    {
146  1 DisplayMacroParameters parameters = new DisplayMacroParameters();
147   
148  1 try {
149  1 this.displayMacro.execute(parameters, null, createMacroTransformationContext("whatever", false));
150  0 Assert.fail("An exception should have been thrown");
151    } catch (MacroExecutionException expected) {
152  1 Assert.assertEquals("You must specify a 'reference' parameter pointing to the entity to display.",
153    expected.getMessage());
154    }
155    }
156   
157    /**
158    * Verify that relative links returned by the display macro as wrapped with a MetaDataBlock.
159    */
 
160  0 toggle @Test
161    public void testDisplayMacroWhenDisplayingDocumentWithRelativeReferences() throws Exception
162    {
163    // @formatter:off
164  0 String expected = "beginDocument\n"
165    + "beginMetaData [[base]=[displayedWiki:displayedSpace.displayedPage]"
166    + "[source]=[displayedWiki:displayedSpace.displayedPage][syntax]=[XWiki 2.0]]\n"
167    + "beginParagraph\n"
168    + "beginLink [Typed = [false] Type = [doc] Reference = [page]] [false]\n"
169    + "endLink [Typed = [false] Type = [doc] Reference = [page]] [false]\n"
170    + "onSpace\n"
171    + "beginLink [Typed = [true] Type = [attach] Reference = [test.png]] [false]\n"
172    + "endLink [Typed = [true] Type = [attach] Reference = [test.png]] [false]\n"
173    + "onSpace\n"
174    + "onImage [Typed = [false] Type = [attach] Reference = [test.png]] [true]\n"
175    + "endParagraph\n"
176    + "endMetaData [[base]=[displayedWiki:displayedSpace.displayedPage]"
177    + "[source]=[displayedWiki:displayedSpace.displayedPage][syntax]=[XWiki 2.0]]\n"
178    + "endDocument";
179    // @formatter:on
180   
181  0 final DocumentReference displayedDocumentReference =
182    new DocumentReference("displayedWiki", "displayedSpace", "displayedPage");
183  0 setUpDocumentMock("displayedWiki:displayedSpace.displayedPage", displayedDocumentReference,
184    "[[page]] [[attach:test.png]] image:test.png");
185  0 getMockery().checking(new Expectations()
186    {
 
187  0 toggle {
188  0 oneOf(mockContextualAuthorization).hasAccess(with(Right.VIEW), with(any(DocumentReference.class)));
189  0 will(returnValue(true));
190  0 oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)),
191    with(any(DocumentModelBridge.class)));
192  0 oneOf(mockSetup.bridge).getCurrentDocumentReference();
193  0 will(returnValue(displayedDocumentReference));
194  0 oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class)));
195    }
196    });
197   
198  0 DisplayMacroParameters parameters = new DisplayMacroParameters();
199  0 parameters.setReference("displayedWiki:displayedSpace.displayedPage");
200   
201  0 List<Block> blocks =
202    Test failure here this.displayMacro.execute(parameters, null, createMacroTransformationContext("whatever", false));
203   
204  0 assertBlocks(expected, blocks, this.rendererFactory);
205    }
206   
 
207    private static class ExpectedRecursiveInclusionException extends RuntimeException
208    {
209    }
210   
 
211  1 toggle @Test
212    public void testDisplayMacroWithRecursiveDisplay() throws Exception
213    {
214  1 final DocumentDisplayer mockDocumentDisplayer = getMockery().mock(DocumentDisplayer.class);
215   
216  1 this.displayMacro.setDocumentAccessBridge(mockSetup.bridge);
217  1 FieldUtils.writeField(this.displayMacro, "documentDisplayer", mockDocumentDisplayer, true);
218   
219  1 final MacroTransformationContext macroContext = createMacroTransformationContext("wiki:space.page", false);
220   
221  1 final DisplayMacroParameters parameters = new DisplayMacroParameters();
222  1 parameters.setReference("wiki:space.page");
223   
224  1 final DocumentReference includedDocumentReference = new DocumentReference("wiki", "space", "page");
225  1 setUpDocumentMock("wiki:space.page", includedDocumentReference, "");
226  1 getMockery().checking(new Expectations()
227    {
 
228  1 toggle {
229  1 allowing(mockContextualAuthorization).hasAccess(with(Right.VIEW), with(any(DocumentReference.class)));
230  1 will(returnValue(true));
231   
232  1 allowing(mockDocumentDisplayer).display(with(same(mockDocument)),
233    with(any(DocumentDisplayerParameters.class)));
234  1 will(new CustomAction("recursively call the include macro again")
235    {
 
236  1 toggle @Override
237    public Object invoke(Invocation invocation) throws Throwable
238    {
239  1 try {
240  1 displayMacro.execute(parameters, null, macroContext);
241    } catch (Exception expected) {
242  1 if (expected.getMessage().contains("Found recursive display")) {
243  1 throw new ExpectedRecursiveInclusionException();
244    }
245    }
246  0 return true;
247    }
248    });
249    }
250    });
251   
252  1 try {
253  1 this.displayMacro.execute(parameters, null, macroContext);
254  0 Assert.fail("The display macro hasn't checked the recursive display");
255    } catch (MacroExecutionException expected) {
256  1 if (!(expected.getCause() instanceof ExpectedRecursiveInclusionException)) {
257  0 throw expected;
258    }
259    }
260    }
261   
 
262  0 toggle @Test
263    public void testDisplayMacroInsideBaseMetaDataBlockAndWithRelativeDocumentReferencePassed() throws Exception
264    {
265    // @formatter:off
266  0 String expected = "beginDocument\n"
267    + "beginMetaData [[base]=[wiki:space.relativePage][source]=[wiki:space.relativePage][syntax]=[XWiki 2.0]]\n"
268    + "beginParagraph\n"
269    + "onWord [content]\n"
270    + "endParagraph\n"
271    + "endMetaData [[base]=[wiki:space.relativePage][source]=[wiki:space.relativePage][syntax]=[XWiki 2.0]]\n"
272    + "endDocument";
273    // @formatter:on
274   
275  0 DisplayMacroParameters parameters = new DisplayMacroParameters();
276  0 parameters.setReference("relativePage");
277   
278  0 MacroTransformationContext macroContext = createMacroTransformationContext("whatever", false);
279    // Add a Source MetaData Block as a parent of the display Macro block.
280  0 new MetaDataBlock(Collections.<Block>singletonList(macroContext.getCurrentMacroBlock()),
281    new MetaData(Collections.<String, Object>singletonMap(MetaData.BASE, "wiki:space.page")));
282   
283  0 final DocumentReference sourceReference = new DocumentReference("wiki", "space", "page");
284  0 final DocumentReference resolvedReference = new DocumentReference("wiki", "space", "relativePage");
285  0 setUpDocumentMock("relativePage", resolvedReference, "content");
286   
287  0 getMockery().checking(new Expectations()
288    {
 
289  0 toggle {
290  0 allowing(mockEntityReferenceResolver).resolve(with("wiki:space.page"), with(EntityType.DOCUMENT),
291    with(IsArray.array(any(MacroBlock.class))));
292  0 will(returnValue(sourceReference));
293  0 allowing(mockEntityReferenceResolver).resolve(with("relativePage"), with(EntityType.DOCUMENT),
294    with(IsArray.array(any(MacroBlock.class))));
295  0 will(returnValue(resolvedReference));
296  0 allowing(mockContextualAuthorization).hasAccess(with(Right.VIEW), with(resolvedReference));
297  0 will(returnValue(true));
298  0 oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)), with(same(mockDocument)));
299  0 oneOf(mockSetup.bridge).getCurrentDocumentReference();
300  0 will(returnValue(resolvedReference));
301  0 oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class)));
302    }
303    });
304   
305  0 Test failure here List<Block> blocks = this.displayMacro.execute(parameters, null, macroContext);
306   
307  0 assertBlocks(expected, blocks, this.rendererFactory);
308    }
309   
 
310  0 toggle @Test
311    public void testDisplayMacroWhenSectionSpecified() throws Exception
312    {
313    // @formatter:off
314  0 String expected =
315    "beginDocument\n"
316    + "beginMetaData [[base]=[wiki:Space.DisplayedPage][source]=[wiki:Space.DisplayedPage]"
317    + "[syntax]=[XWiki 2.0]]\n"
318    + "beginHeader [1, Hsection]\n"
319    + "onWord [section]\n"
320    + "endHeader [1, Hsection]\n"
321    + "beginParagraph\n"
322    + "onWord [content2]\n"
323    + "endParagraph\n"
324    + "endMetaData [[base]=[wiki:Space.DisplayedPage][source]=[wiki:Space.DisplayedPage]"
325    + "[syntax]=[XWiki 2.0]]\n"
326    + "endDocument";
327    // @formatter:on
328   
329  0 DisplayMacroParameters parameters = new DisplayMacroParameters();
330  0 parameters.setSection("Hsection");
331   
332  0 Test failure here List<Block> blocks = runDisplayMacro(parameters, "content1\n\n= section =\ncontent2");
333   
334  0 assertBlocks(expected, blocks, this.rendererFactory);
335    }
336   
 
337  0 toggle @Test
338    public void testDisplayMacroWhenInvalidSectionSpecified() throws Exception
339    {
340  0 DisplayMacroParameters parameters = new DisplayMacroParameters();
341  0 parameters.setSection("unknown");
342   
343  0 try {
344  0 runDisplayMacro(parameters, "content");
345  0 Assert.fail("Should have raised an exception");
346    } catch (MacroExecutionException expected) {
347  0 Test failure here Assert.assertEquals("Cannot find section [unknown] in document [wiki:Space.DisplayedPage]",
348    expected.getMessage());
349    }
350    }
351   
 
352  6 toggle private MacroTransformationContext createMacroTransformationContext(String documentName, boolean isInline)
353    {
354  6 MacroTransformationContext context = new MacroTransformationContext();
355  6 MacroBlock displayMacro =
356    new MacroBlock("display", Collections.singletonMap("reference", documentName), isInline);
357  6 context.setCurrentMacroBlock(displayMacro);
358  6 return context;
359    }
360   
 
361  5 toggle private void setUpDocumentMock(final String resolve, final DocumentReference reference, final String content)
362    throws Exception
363    {
364  5 mockDocument = getMockery().mock(DocumentModelBridge.class, resolve);
365  5 getMockery().checking(new Expectations()
366    {
 
367  5 toggle {
368  5 allowing(mockEntityReferenceResolver).resolve(with(resolve), with(EntityType.DOCUMENT),
369    with(IsArray.array(any(MacroBlock.class))));
370  5 will(returnValue(reference));
371  5 allowing(mockSetup.bridge).getDocumentInstance((EntityReference) reference);
372  5 will(returnValue(mockDocument));
373  5 allowing(mockSetup.bridge).getTranslatedDocumentInstance(reference);
374  5 will(returnValue(mockDocument));
375  5 allowing(mockDocument).getSyntax();
376  5 will(returnValue(Syntax.XWIKI_2_0));
377  5 allowing(mockDocument).getXDOM();
378  5 will(returnValue(getXDOM(content)));
379  5 allowing(mockDocument).getDocumentReference();
380  5 will(returnValue(reference));
381  5 allowing(mockDocument).getRealLanguage();
382  5 will(returnValue(""));
383    }
384    });
385    }
386   
 
387  5 toggle private XDOM getXDOM(String content) throws Exception
388    {
389  5 Parser xwiki20Parser = getComponentManager().getInstance(Parser.class, "xwiki/2.0");
390  5 return xwiki20Parser.parse(new StringReader(content));
391    }
392   
 
393  0 toggle private List<Block> runDisplayMacroWithPreVelocity(String velocity, String displayedContent) throws Exception
394    {
395  0 Test failure here VelocityManager velocityManager = getComponentManager().getInstance(VelocityManager.class);
396  0 StringWriter writer = new StringWriter();
397  0 velocityManager.getVelocityEngine().evaluate(velocityManager.getVelocityContext(), writer,
398    "wiki:Space.DisplayingPage", velocity);
399   
400  0 return runDisplayMacro(displayedContent);
401    }
402   
 
403  0 toggle private List<Block> runDisplayMacro(String displayedContent) throws Exception
404    {
405  0 return runDisplayMacro(new DisplayMacroParameters(), displayedContent);
406    }
407   
 
408  0 toggle private List<Block> runDisplayMacro(DisplayMacroParameters parameters, String displayedContent) throws Exception
409    {
410  0 final DocumentReference displayedDocumentReference = new DocumentReference("wiki", "Space", "DisplayedPage");
411  0 String displayedDocStringRef = "wiki:space.page";
412  0 setUpDocumentMock(displayedDocStringRef, displayedDocumentReference, displayedContent);
413  0 getMockery().checking(new Expectations()
414    {
 
415  0 toggle {
416  0 oneOf(mockContextualAuthorization).hasAccess(with(Right.VIEW), with(same(displayedDocumentReference)));
417  0 will(returnValue(true));
418  0 oneOf(mockSetup.bridge).pushDocumentInContext(with(any(Map.class)), with(same(mockDocument)));
419  0 atMost(1).of(mockSetup.bridge).getCurrentDocumentReference();
420  0 will(returnValue(displayedDocumentReference));
421  0 oneOf(mockSetup.bridge).popDocumentFromContext(with(any(Map.class)));
422    }
423    });
424  0 this.displayMacro.setDocumentAccessBridge(this.mockSetup.bridge);
425   
426  0 parameters.setReference(displayedDocStringRef);
427   
428    // Create a Macro transformation context with the Macro transformation object defined so that the display
429    // macro can transform displayed page which is using a new context.
430  0 MacroTransformation macroTransformation =
431    (MacroTransformation) getComponentManager().getInstance(Transformation.class, "macro");
432  0 MacroTransformationContext macroContext = createMacroTransformationContext(displayedDocStringRef, false);
433  0 macroContext.setId("wiki:Space.DisplayingPage");
434  0 macroContext.setTransformation(macroTransformation);
435   
436  0 Test failure here return this.displayMacro.execute(parameters, null, macroContext);
437    }
438    }