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

File DisplayMacroTest.java

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

Code metrics

4
128
21
2
402
310
27
0.21
6.1
10.5
1.29

Classes

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