1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.doc

File XWikiAttachmentTest.java

 

Code metrics

2
152
16
2
407
290
18
0.12
9.5
8
1.12

Classes

Class Line # Actions
XWikiAttachmentTest 65 144 0% 14 1
0.993630699.4%
XWikiAttachmentTest.RandomInputStream 109 8 0% 4 0
1.0100%
 

Contributing tests

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