1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package com.xpn.xwiki.doc

File XWikiAttachmentTest.java

 

Code metrics

2
159
17
2
426
302
19
0.12
9.35
8.5
1.12

Classes

Class Line # Actions
XWikiAttachmentTest 67 151 0% 15 1
0.993939499.4%
XWikiAttachmentTest.RandomInputStream 112 8 0% 4 0
1.0100%
 

Contributing tests

This file is covered by 13 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 com.xpn.xwiki.doc;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.IOException;
24    import java.io.InputStream;
25    import java.io.OutputStream;
26    import java.io.StringReader;
27    import java.util.Date;
28   
29    import org.apache.commons.io.IOUtils;
30    import org.apache.commons.io.input.ReaderInputStream;
31    import org.junit.Before;
32    import org.junit.Rule;
33    import org.junit.Test;
34    import org.xwiki.environment.Environment;
35    import org.xwiki.model.EntityType;
36    import org.xwiki.model.reference.AttachmentReference;
37    import org.xwiki.model.reference.AttachmentReferenceResolver;
38    import org.xwiki.model.reference.DocumentReference;
39    import org.xwiki.model.reference.DocumentReferenceResolver;
40    import org.xwiki.model.reference.EntityReference;
41    import org.xwiki.model.reference.EntityReferenceResolver;
42    import org.xwiki.model.reference.EntityReferenceSerializer;
43    import org.xwiki.test.LogRule;
44   
45    import com.xpn.xwiki.store.AttachmentVersioningStore;
46    import com.xpn.xwiki.test.MockitoOldcoreRule;
47    import com.xpn.xwiki.test.component.XWikiDocumentFilterUtilsComponentList;
48    import com.xpn.xwiki.user.api.XWikiRightService;
49   
50    import static org.junit.Assert.assertEquals;
51    import static org.junit.Assert.assertFalse;
52    import static org.junit.Assert.assertNull;
53    import static org.junit.Assert.assertSame;
54    import static org.junit.Assert.assertTrue;
55    import static org.junit.Assert.fail;
56    import static org.mockito.ArgumentMatchers.any;
57    import static org.mockito.ArgumentMatchers.eq;
58    import static org.mockito.Mockito.mock;
59    import static org.mockito.Mockito.when;
60   
61    /**
62    * Unit tests for {@link XWikiAttachment}.
63    *
64    * @version $Id: 1da4c90fce0dc64988756488b23dd6aa0aa25e70 $
65    */
66    @XWikiDocumentFilterUtilsComponentList
 
67    public class XWikiAttachmentTest
68    {
69    @Rule
70    public MockitoOldcoreRule oldcore = new MockitoOldcoreRule();
71   
72    @Rule
73    public LogRule logger = new LogRule();
74   
 
75  13 toggle @Before
76    public void configure() throws Exception
77    {
78  13 this.logger.recordLoggingForType(XWikiAttachment.class);
79   
80  13 this.oldcore.getMocker().registerMockComponent(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
81  13 this.oldcore.getMocker().registerMockComponent(AttachmentReferenceResolver.TYPE_STRING, "current");
82  13 this.oldcore.getMocker().registerMockComponent(Environment.class);
83    }
84   
85    /**
86    * Unit test for <a href="https://jira.xwiki.org/browse/XWIKI-9075">XWIKI-9075</a> to prove that calling
87    * {@code fromXML} doesn't set the metadata dirty flag.
88    * <p>
89    * Note: I think there's a bug in that fromXML should return a new instance of XWikiAttachment and not modify the
90    * current one as this would mean changing its identity...
91    */
 
92  1 toggle @Test
93    public void fromXML() throws Exception
94    {
95  1 XWikiAttachment attachment = new XWikiAttachment();
96  1 attachment.fromXML("<attachment>\n" + "<filename>XWikiLogo.png</filename>\n" + "<filesize>1390</filesize>\n"
97    + "<mimetype>image/png2</mimetype>\n" + "<author>xwiki:XWiki.Admin</author>\n"
98    + "<date>1252454400000</date>\n" + "<version>1.1</version>\n" + "<comment/>\n"
99    + "<content>MDEyMzQ1Njc4OQ==</content>\n" + "</attachment>");
100   
101  1 assertEquals("XWikiLogo.png", attachment.getFilename());
102  1 assertEquals(new Date(1252454400000L), attachment.getDate());
103  1 assertEquals("1.1", attachment.getVersion());
104  1 assertEquals("0123456789", IOUtils.toString(attachment.getContentInputStream(null)));
105  1 assertEquals("image/png2", attachment.getMimeType());
106  1 assertEquals("image/png2", attachment.getMimeType(null));
107   
108  1 assertFalse(attachment.isMetaDataDirty());
109    }
110   
111    /** An InputStream which will return a stream of random bytes of length given in the constructor. */
 
112    private static class RandomInputStream extends InputStream
113    {
114    private int bytes;
115   
116    private int state;
117   
 
118  7 toggle public RandomInputStream(final int bytes, final int seed)
119    {
120  7 this.bytes = bytes;
121  7 this.state = seed;
122    }
123   
 
124  1 toggle @Override
125    public int available()
126    {
127  1 return this.bytes;
128    }
129   
 
130  40114 toggle @Override
131    public int read()
132    {
133  40114 if (this.bytes == 0) {
134  14 return -1;
135    }
136  40100 this.bytes--;
137  40100 this.state = this.state << 13 | this.state >>> 19;
138  40100 return ++this.state & 0xff;
139    }
140    }
141   
142    // Tests
143   
 
144  1 toggle @Test
145    public void testGetSize() throws IOException
146    {
147  1 XWikiAttachment attachment = new XWikiAttachment();
148   
149  1 assertEquals(-1, attachment.getLongSize());
150   
151  1 attachment.setLongSize(42);
152   
153  1 assertEquals(42, attachment.getLongSize());
154   
155  1 attachment.setContent(new ByteArrayInputStream(new byte[] { 1, 2, 3, 4 }));
156   
157  1 assertEquals(4, attachment.getLongSize());
158   
159  1 attachment.setLongSize(42);
160   
161  1 assertEquals(4, attachment.getLongSize());
162    }
163   
 
164  1 toggle @Test
165    public void testGetVersionList() throws Exception
166    {
167  1 final XWikiAttachment attach = new XWikiAttachment();
168  1 attach.setVersion("1.1");
169  1 assertEquals("Version list was not one element long for version 1.1", 1, attach.getVersionList().size());
170  1 attach.setVersion("1.2");
171  1 assertEquals("Version list was not two elements long for version 1.2.", 2, attach.getVersionList().size());
172  1 attach.setVersion("1.3");
173  1 assertEquals("Version list was not two elements long for version 1.3.", 3, attach.getVersionList().size());
174    }
175   
176    /**
177    * Create an attachment, populate it with enough data to make it flush to disk cache, read back data and make sure
178    * it's the same.
179    */
 
180  1 toggle @Test
181    public void testStoreContentInDiskCache() throws Exception
182    {
183  1 int attachLength = 20000;
184    // Check for data dependent errors.
185  1 int seed = (int) System.currentTimeMillis();
186  1 final XWikiAttachment attach = new XWikiAttachment();
187  1 final InputStream ris = new RandomInputStream(attachLength, seed);
188  1 attach.setContent(ris);
189  1 assertEquals("Not all of the stream was read", 0, ris.available());
190  1 assertTrue(IOUtils.contentEquals(new RandomInputStream(attachLength, seed),
191    attach.getAttachment_content().getContentInputStream()));
192    }
193   
 
194  1 toggle @Test
195    public void testSetContentViaOutputStream() throws Exception
196    {
197  1 int attachLength = 20;
198  1 int seed = (int) System.currentTimeMillis();
199  1 final XWikiAttachment attach = new XWikiAttachment();
200  1 final InputStream ris = new RandomInputStream(attachLength, seed);
201  1 attach.setContent(ris);
202  1 assertTrue(IOUtils.contentEquals(new RandomInputStream(attachLength, seed),
203    attach.getAttachment_content().getContentInputStream()));
204    // Now write to the attachment via an OutputStream.
205  1 final XWikiAttachmentContent xac = attach.getAttachment_content();
206  1 xac.setContentDirty(false);
207  1 final OutputStream os = xac.getContentOutputStream();
208   
209    // Adding content with seed+1 will make a radically different set of content.
210  1 IOUtils.copy(new RandomInputStream(attachLength, seed + 1), os);
211   
212    // It should still be the old content.
213  1 assertTrue(IOUtils.contentEquals(new RandomInputStream(attachLength, seed), xac.getContentInputStream()));
214  1 assertFalse(xac.isContentDirty());
215   
216  1 os.close();
217   
218    // Now it should be the new content.
219  1 assertTrue(IOUtils.contentEquals(new RandomInputStream(attachLength, seed + 1), xac.getContentInputStream()));
220  1 assertTrue(xac.isContentDirty());
221    }
222   
 
223  1 toggle @Test
224    public void testSetContentWithMaxSize() throws Exception
225    {
226  1 XWikiAttachment attachment = new XWikiAttachment();
227   
228  1 attachment.setContent(new ReaderInputStream(new StringReader("123456789")), 5);
229   
230  1 assertEquals("12345", IOUtils.toString(attachment.getContentInputStream(null)));
231    }
232   
 
233  1 toggle @Test
234    public void testGetMime() throws Exception
235    {
236  1 XWikiAttachment attachment = new XWikiAttachment();
237   
238  1 attachment.setFilename("image.jpg");
239   
240  1 assertNull("image/jpeg", attachment.getMimeType());
241  1 assertEquals("image/jpeg", attachment.getMimeType(null));
242   
243  1 attachment.setFilename("xml.xml");
244   
245  1 assertEquals("application/xml", attachment.getMimeType(null));
246   
247  1 attachment.setFilename("zip.zip");
248   
249  1 assertEquals("application/zip", attachment.getMimeType(null));
250   
251  1 attachment.setFilename("unknown");
252  1 attachment.setDoc(new XWikiDocument(new DocumentReference("wiki", "Space", "Page")));
253  1 assertEquals(0, this.logger.size());
254  1 assertEquals("application/octet-stream", attachment.getMimeType(null));
255  1 assertTrue(this.logger.contains("Failed to read the content of "
256    + "[Attachment wiki:Space.Page@unknown] in order to detect its mime type."));
257   
258    // Test content-based detection.
259  1 attachment.setFilename("unknown");
260  1 attachment.setContent(new ByteArrayInputStream("content".getBytes()));
261  1 assertEquals("text/plain", attachment.getMimeType(null));
262    }
263   
 
264  1 toggle @Test
265    public void testSetMimeType()
266    {
267  1 XWikiAttachment attachment = new XWikiAttachment();
268   
269  1 assertEquals(null, attachment.getMimeType());
270  1 assertEquals("application/octet-stream", attachment.getMimeType(null));
271   
272  1 attachment.setMimeType("image/jpeg");
273   
274  1 assertEquals("image/jpeg", attachment.getMimeType());
275  1 assertEquals("image/jpeg", attachment.getMimeType(null));
276    }
277   
 
278  1 toggle @Test
279    public void testResetMimeType()
280    {
281  1 XWikiAttachment attachment = new XWikiAttachment();
282   
283  1 assertEquals(null, attachment.getMimeType());
284  1 assertEquals("application/octet-stream", attachment.getMimeType(null));
285   
286  1 attachment.resetMimeType(null);
287   
288  1 assertEquals("application/octet-stream", attachment.getMimeType());
289  1 assertEquals("application/octet-stream", attachment.getMimeType(null));
290    }
291   
 
292  1 toggle @Test
293    public void testAuthorWithDocument() throws Exception
294    {
295  1 EntityReferenceSerializer<String> compactWikiEntityReferenceSerializer =
296    this.oldcore.getMocker().getInstance(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
297  1 DocumentReferenceResolver<EntityReference> explicitDocumentReferenceResolver =
298    this.oldcore.getMocker().registerMockComponent(DocumentReferenceResolver.TYPE_REFERENCE, "explicit");
299  1 EntityReferenceResolver<String> xclassEntityReferenceResolver =
300    this.oldcore.getMocker().registerMockComponent(EntityReferenceResolver.TYPE_STRING, "xclass");
301   
302  1 XWikiDocument document = new XWikiDocument(new DocumentReference("wiki", "space", "page"));
303  1 XWikiAttachment attachment = new XWikiAttachment(document, "filename");
304   
305    // getAuthor() based on getAuthorReference()
306  1 DocumentReference userReference = new DocumentReference("userwiki", "userspace", "userpage");
307  1 attachment.setAuthorReference(userReference);
308  1 assertEquals(userReference, attachment.getAuthorReference());
309  1 when(compactWikiEntityReferenceSerializer.serialize(userReference, attachment.getReference()))
310    .thenReturn("stringUserReference");
311  1 assertEquals("stringUserReference", attachment.getAuthor());
312   
313    // getAuthorReference() based on getAuthor()
314  1 attachment.setAuthor("author");
315  1 assertEquals("author", attachment.getAuthor());
316  1 userReference = new DocumentReference("wiki", "XWiki", "author");
317  1 EntityReference relativeUserReference = userReference.removeParent(userReference.getWikiReference());
318  1 when(xclassEntityReferenceResolver.resolve("author", EntityType.DOCUMENT)).thenReturn(relativeUserReference);
319  1 when(explicitDocumentReferenceResolver.resolve(relativeUserReference, attachment.getReference()))
320    .thenReturn(userReference);
321  1 assertEquals(userReference, attachment.getAuthorReference());
322   
323    // Guest author.
324  1 attachment.setAuthor(XWikiRightService.GUEST_USER);
325  1 userReference = new DocumentReference("wiki", "XWiki", XWikiRightService.GUEST_USER);
326  1 relativeUserReference = userReference.removeParent(userReference.getWikiReference());
327  1 when(xclassEntityReferenceResolver.resolve(any(String.class), eq(EntityType.DOCUMENT)))
328    .thenReturn(relativeUserReference);
329  1 when(explicitDocumentReferenceResolver.resolve(relativeUserReference, attachment.getReference()))
330    .thenReturn(userReference);
331  1 assertNull(attachment.getAuthorReference());
332    }
333   
 
334  1 toggle @Test
335    public void testAuthorWithoutDocument() throws Exception
336    {
337  1 EntityReferenceSerializer<String> compactWikiEntityReferenceSerializer =
338    this.oldcore.getMocker().getInstance(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
339  1 AttachmentReferenceResolver<String> currentAttachmentReferenceResolver =
340    this.oldcore.getMocker().getInstance(AttachmentReferenceResolver.TYPE_STRING, "current");
341  1 DocumentReferenceResolver<EntityReference> explicitDocumentReferenceResolver =
342    this.oldcore.getMocker().registerMockComponent(DocumentReferenceResolver.TYPE_REFERENCE, "explicit");
343  1 EntityReferenceResolver<String> xclassEntityReferenceResolver =
344    this.oldcore.getMocker().registerMockComponent(EntityReferenceResolver.TYPE_STRING, "xclass");
345   
346  1 XWikiAttachment attachment = new XWikiAttachment(null, "filename");
347  1 DocumentReference currentDocumentReference =
348    new DocumentReference("currentWiki", "currentSpage", "currentPage");
349  1 AttachmentReference attachmentReference =
350    new AttachmentReference(attachment.getFilename(), currentDocumentReference);
351   
352    // getAuthor() based on getAuthorReference()
353  1 DocumentReference userReference = new DocumentReference("userwiki", "userspace", "userpage");
354  1 attachment.setAuthorReference(userReference);
355  1 assertEquals(userReference, attachment.getAuthorReference());
356  1 when(currentAttachmentReferenceResolver.resolve(attachment.getFilename())).thenReturn(attachmentReference);
357  1 when(compactWikiEntityReferenceSerializer.serialize(userReference, attachmentReference))
358    .thenReturn("stringUserReference");
359  1 assertEquals("stringUserReference", attachment.getAuthor());
360   
361    // getAuthorReference() based on getAuthor()
362  1 attachment.setAuthor("author");
363  1 assertEquals("author", attachment.getAuthor());
364  1 userReference = new DocumentReference("wiki", "XWiki", "author");
365  1 EntityReference relativeUserReference = userReference.removeParent(userReference.getWikiReference());
366  1 when(xclassEntityReferenceResolver.resolve("author", EntityType.DOCUMENT)).thenReturn(relativeUserReference);
367  1 when(explicitDocumentReferenceResolver.resolve(relativeUserReference, attachment.getReference()))
368    .thenReturn(userReference);
369  1 assertEquals(userReference, attachment.getAuthorReference());
370    }
371   
 
372  1 toggle @Test
373    public void getContentInputStreamForLatestVersion() throws Exception
374    {
375  1 XWikiDocument document = mock(XWikiDocument.class);
376  1 when(document.getDocumentReference()).thenReturn(new DocumentReference("wiki", "Space", "Page"));
377   
378  1 when(this.oldcore.getXWikiContext().getWiki().getDocument(document.getDocumentReference(),
379    this.oldcore.getXWikiContext())).thenReturn(document);
380   
381  1 XWikiAttachment attachment = new XWikiAttachment(document, "file.txt");
382  1 when(document.getAttachment(attachment.getFilename())).thenReturn(attachment);
383  1 attachment.setVersion("3.5");
384   
385  1 try {
386  1 attachment.getContentInputStream(this.oldcore.getXWikiContext());
387  0 fail();
388    } catch (NullPointerException e) {
389    // Expected because the attachment content is not set. The attachment content is normally set by the
390    // loadAttachmentContent call we verify below.
391    }
392    }
393   
 
394  1 toggle @Test
395    public void getContentInputStreamFromArchive() throws Exception
396    {
397  1 XWikiDocument document = mock(XWikiDocument.class);
398  1 when(document.getDocumentReference()).thenReturn(new DocumentReference("wiki", "Space", "Page"));
399   
400  1 when(this.oldcore.getXWikiContext().getWiki().getDocument(document.getDocumentReference(),
401    this.oldcore.getXWikiContext())).thenReturn(document);
402   
403  1 XWikiAttachment attachment = new XWikiAttachment(document, "file.txt");
404  1 attachment.setVersion("3.5");
405   
406  1 XWikiAttachment newAttachment = new XWikiAttachment(document, attachment.getFilename());
407  1 newAttachment.setVersion("5.1");
408  1 when(document.getAttachment(attachment.getFilename())).thenReturn(newAttachment);
409   
410  1 XWikiAttachmentContent content = mock(XWikiAttachmentContent.class);
411  1 when(content.getContentInputStream()).thenReturn(mock(InputStream.class));
412   
413  1 XWikiAttachment archivedAttachment = new XWikiAttachment(document, attachment.getFilename());
414  1 archivedAttachment.setAttachment_content(content);
415   
416  1 XWikiAttachmentArchive archive = mock(XWikiAttachmentArchive.class);
417  1 when(archive.getRevision(attachment, attachment.getVersion(), this.oldcore.getXWikiContext()))
418    .thenReturn(archivedAttachment);
419   
420  1 AttachmentVersioningStore store = mock(AttachmentVersioningStore.class);
421  1 when(this.oldcore.getXWikiContext().getWiki().getDefaultAttachmentArchiveStore()).thenReturn(store);
422  1 when(store.loadArchive(attachment, this.oldcore.getXWikiContext(), true)).thenReturn(archive);
423   
424  1 assertSame(content.getContentInputStream(), attachment.getContentInputStream(this.oldcore.getXWikiContext()));
425    }
426    }