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

File FilesystemAttachmentStoreTest.java

 

Code metrics

6
135
20
1
377
285
26
0.19
6.75
20
1.3

Classes

Class Line # Actions
FilesystemAttachmentStoreTest 69 135 0% 26 4
0.975155397.5%
 

Contributing tests

This file is covered by 6 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.store.legacy.store.internal;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.ByteArrayOutputStream;
24    import java.io.File;
25    import java.io.FileOutputStream;
26    import java.io.IOException;
27    import java.io.InputStream;
28    import java.io.OutputStream;
29    import java.io.UnsupportedEncodingException;
30    import java.nio.charset.StandardCharsets;
31    import java.util.ArrayList;
32    import java.util.List;
33   
34    import org.apache.commons.io.FileUtils;
35    import org.apache.commons.io.IOUtils;
36    import org.apache.commons.lang3.reflect.FieldUtils;
37    import org.hibernate.Session;
38    import org.jmock.Expectations;
39    import org.jmock.api.Invocation;
40    import org.jmock.lib.action.CustomAction;
41    import org.jmock.lib.legacy.ClassImposteriser;
42    import org.junit.After;
43    import org.junit.Assert;
44    import org.junit.Before;
45    import org.junit.Test;
46    import org.xwiki.model.reference.AttachmentReference;
47    import org.xwiki.model.reference.DocumentReference;
48    import org.xwiki.store.filesystem.internal.FilesystemStoreTools;
49    import org.xwiki.store.legacy.doc.internal.FilesystemAttachmentContent;
50    import org.xwiki.store.locks.dummy.internal.DummyLockProvider;
51   
52    import com.xpn.xwiki.XWiki;
53    import com.xpn.xwiki.XWikiContext;
54    import com.xpn.xwiki.doc.XWikiAttachment;
55    import com.xpn.xwiki.doc.XWikiAttachment.AttachmentContainer;
56    import com.xpn.xwiki.doc.XWikiAttachmentArchive;
57    import com.xpn.xwiki.doc.XWikiAttachmentContent;
58    import com.xpn.xwiki.doc.XWikiDocument;
59    import com.xpn.xwiki.store.AttachmentVersioningStore;
60    import com.xpn.xwiki.store.XWikiHibernateStore;
61    import com.xpn.xwiki.web.Utils;
62   
63    /**
64    * Tests for FilesystemAttachmentStore.
65    *
66    * @version $Id: 10bffc92ab215bb5afc7570f3fde7508440431e4 $
67    * @since 3.0M2
68    */
 
69    public class FilesystemAttachmentStoreTest extends AbstractFilesystemAttachmentStoreTest
70    {
71    private static final String HELLO = "Hello World";
72   
73    private static final byte[] HELLO_BYTES;
74   
75    private static final InputStream HELLO_STREAM;
76   
77    private XWikiContext mockContext;
78   
79    private XWikiAttachment mockAttach;
80   
81    private AttachmentReference mockAttachReference;
82   
83    private FilesystemAttachmentStore attachStore;
84   
85    private FilesystemStoreTools fileTools;
86   
87    private AttachmentVersioningStore mockAttachVersionStore;
88   
89    private XWikiAttachmentArchive mockArchive;
90   
91    private XWikiHibernateStore mockHibernate;
92   
93    private Session mockHibernateSession;
94   
95    private XWikiDocument doc;
96   
97    /**
98    * The file which will hold content for this attachment.
99    */
100    private File storeFile;
101   
102    /**
103    * The dir in /tmp/ which we use as our sandbox.
104    */
105    private File storageLocation;
106   
 
107  1 toggle static {
108  1 try {
109  1 HELLO_BYTES = HELLO.getBytes("UTF-8");
110  1 HELLO_STREAM = new ByteArrayInputStream(HELLO_BYTES);
111    } catch (UnsupportedEncodingException e) {
112  0 throw new RuntimeException("No UTF-8!!");
113    }
114    }
115   
 
116  6 toggle @Before
117    @Override
118    public void setUp() throws Exception
119    {
120  6 super.setUp();
121  6 getMockery().setImposteriser(ClassImposteriser.INSTANCE);
122   
123  6 Utils.setComponentManager(this.getComponentManager());
124   
125  6 this.mockContext = getMockery().mock(XWikiContext.class);
126  6 final XWiki mockXWiki = getMockery().mock(XWiki.class);
127  6 this.mockHibernate = getMockery().mock(XWikiHibernateStore.class);
128  6 final XWikiAttachmentContent mockDirtyContent = getMockery().mock(XWikiAttachmentContent.class);
129  6 this.mockAttachVersionStore = getMockery().mock(AttachmentVersioningStore.class);
130  6 this.mockArchive = getMockery().mock(XWikiAttachmentArchive.class);
131  6 this.mockHibernateSession = getMockery().mock(Session.class);
132  6 this.doc = new XWikiDocument(new DocumentReference("xwiki", "Main", "WebHome"));
133   
134  6 this.mockAttachReference = new AttachmentReference("file.name", doc.getDocumentReference());
135  6 this.mockAttach = getMockery().mock(XWikiAttachment.class);
136  6 getMockery().checking(new Expectations()
137    {
 
138  6 toggle {
139  6 allowing(mockContext).getWiki();
140  6 will(returnValue(mockXWiki));
141   
142  6 allowing(mockXWiki).getStore();
143  6 will(returnValue(mockHibernate));
144  6 allowing(mockXWiki).getHibernateStore();
145  6 will(returnValue(mockHibernate));
146  6 allowing(mockHibernate).checkHibernate(mockContext);
147  6 allowing(mockHibernate).beginTransaction(mockContext);
148   
149  6 allowing(mockHibernate).getSession(mockContext);
150  6 will(returnValue(mockHibernateSession));
151   
152  6 allowing(mockXWiki).getDefaultAttachmentArchiveStore();
153  6 will(returnValue(mockAttachVersionStore));
154   
155  6 allowing(mockAttach).getContentInputStream(mockContext);
156  6 will(returnValue(HELLO_STREAM));
157  6 allowing(mockAttach).setDoc(doc);
158  6 allowing(mockAttach).getDoc();
159  6 will(returnValue(doc));
160  6 allowing(mockAttach).getFilename();
161  6 will(returnValue(mockAttachReference.getName()));
162  6 allowing(mockAttach).getReference();
163  6 will(returnValue(mockAttachReference));
164  6 allowing(mockAttach).updateContentArchive(mockContext);
165  6 allowing(mockAttach).getAttachment_archive();
166  6 will(returnValue(mockArchive));
167  6 allowing(mockAttach).isArchiveStoreSet();
168  6 will(returnValue(false));
169  6 allowing(mockAttach).getArchiveStore();
170  6 will(returnValue("file"));
171  6 allowing(mockAttach).getAttachment_content();
172  6 will(returnValue(mockDirtyContent));
173  6 allowing(mockAttach).isContentStoreSet();
174  6 will(returnValue(false));
175  6 allowing(mockAttach).getContentStore();
176  6 will(returnValue("file"));
177  6 allowing(mockAttach).isContentDirty();
178  6 will(returnValue(true));
179  6 allowing(mockDirtyContent).isContentDirty();
180  6 will(returnValue(true));
181  6 allowing(mockAttach).setAttachmentContainer(with(any(AttachmentContainer.class)));
182    }
183    });
184   
185  6 final File tmpDir = new File(System.getProperty("java.io.tmpdir"));
186  6 this.storageLocation = new File(tmpDir, "test-storage-location");
187   
188  6 this.fileTools = new FilesystemStoreTools(storageLocation, new DummyLockProvider());
189   
190  6 this.attachStore = new FilesystemAttachmentStore();
191  6 FieldUtils.writeField(this.attachStore, "fileTools", this.fileTools, true);
192   
193  6 this.storeFile = this.fileTools.getAttachmentFileProvider(this.mockAttachReference).getAttachmentContentFile();
194  6 HELLO_STREAM.reset();
195    }
196   
 
197  6 toggle @After
198    @Override
199    public void tearDown() throws IOException
200    {
201  6 resursiveDelete(this.storageLocation);
202    }
203   
 
204  1 toggle @Test
205    public void saveContentTest() throws Exception
206    {
207  1 final File storeFile =
208    this.fileTools.getAttachmentFileProvider(this.mockAttachReference).getAttachmentContentFile();
209  1 Assert.assertFalse(this.storeFile.exists());
210   
211  1 getMockery().checking(new Expectations()
212    {
 
213  1 toggle {
214    // Make sure an archive is saved
215  1 oneOf(mockAttachVersionStore).saveArchive(mockArchive, mockContext, false);
216    }
217    });
218   
219  1 this.attachStore.saveAttachmentContent(this.mockAttach, false, this.mockContext, false);
220   
221  1 Assert.assertTrue("The attachment file was not created.", this.storeFile.exists());
222  1 Assert.assertEquals("The attachment file contained the wrong content", HELLO,
223    FileUtils.readFileToString(storeFile, StandardCharsets.UTF_8));
224    }
225   
 
226  1 toggle @Test
227    public void saveTwoOfSameAttachmentInOneTransactionTest() throws Exception
228    {
229  1 final File storeFile =
230    this.fileTools.getAttachmentFileProvider(this.mockAttachReference).getAttachmentContentFile();
231  1 Assert.assertFalse(this.storeFile.exists());
232   
233  1 getMockery().checking(new Expectations()
234    {
 
235  1 toggle {
236    // Make sure an archive is saved (twice)
237  1 oneOf(mockAttachVersionStore).saveArchive(mockArchive, mockContext, false);
238  1 oneOf(mockAttachVersionStore).saveArchive(mockArchive, mockContext, false);
239    }
240    });
241   
242  1 final List<XWikiAttachment> attachments = new ArrayList<XWikiAttachment>();
243  1 attachments.add(this.mockAttach);
244  1 attachments.add(this.mockAttach);
245  1 this.attachStore.saveAttachmentsContent(attachments, this.doc, false, this.mockContext, false);
246   
247  1 Assert.assertTrue("The attachment file was not created.", this.storeFile.exists());
248  1 Assert.assertEquals("The attachment file contained the wrong content", HELLO,
249    FileUtils.readFileToString(storeFile, StandardCharsets.UTF_8));
250    }
251   
 
252  1 toggle @Test
253    public void loadContentTest() throws Exception
254    {
255  1 this.storeFile.getParentFile().mkdirs();
256  1 OutputStream os = new FileOutputStream(this.storeFile, false);
257  1 IOUtils.copy(HELLO_STREAM, os);
258  1 os.close();
259   
260  1 getMockery().checking(new Expectations()
261    {
 
262  1 toggle {
263  1 oneOf(mockAttach).setAttachment_content(with(any(FilesystemAttachmentContent.class)));
264  1 will(new CustomAction("Check to make sure the attachment content is correct.")
265    {
 
266  1 toggle @Override
267    public Object invoke(final Invocation invoc)
268    {
269  1 final FilesystemAttachmentContent content = (FilesystemAttachmentContent) invoc.getParameter(0);
270   
271  1 try {
272  1 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
273  1 IOUtils.copy(content.getContentInputStream(), baos);
274   
275  1 final String output = new String(baos.toByteArray(), "UTF-8");
276   
277  1 Assert.assertEquals("Not the same attachment content.", HELLO, output);
278  1 return null;
279    } catch (IOException e) {
280  0 throw new RuntimeException("Exception getting attachment content.", e);
281    }
282    }
283    });
284  1 oneOf(mockAttach).setContentStore("file");
285    }
286    });
287   
288  1 this.attachStore.loadAttachmentContent(this.mockAttach, this.mockContext, false);
289    }
290   
 
291  1 toggle @Test
292    public void deleteAttachmentTest() throws Exception
293    {
294  1 getMockery().checking(new Expectations()
295    {
 
296  1 toggle {
297  1 oneOf(mockAttachVersionStore).deleteArchive(mockAttach, mockContext, false);
298  1 exactly(2).of(mockHibernateSession).delete(with(any(Object.class)));
299    }
300    });
301  1 this.createFile();
302   
303  1 this.attachStore.deleteXWikiAttachment(this.mockAttach, false, this.mockContext, false);
304   
305  1 Assert.assertFalse("The attachment file was not deleted.", this.storeFile.exists());
306    }
307   
 
308  1 toggle @Test
309    public void documentUpdateOnDeleteTest() throws Exception
310    {
311  1 final List<XWikiAttachment> attachList = new ArrayList<XWikiAttachment>();
312  1 attachList.add(this.mockAttach);
313  1 this.doc.setAttachmentList(attachList);
314   
315  1 getMockery().checking(new Expectations()
316    {
 
317  1 toggle {
318  1 oneOf(mockAttachVersionStore).deleteArchive(mockAttach, mockContext, false);
319  1 exactly(2).of(mockHibernateSession).delete(with(any(Object.class)));
320  1 oneOf(mockHibernate).saveXWikiDoc(doc, mockContext, false);
321  1 will(new CustomAction("Make sure the attachment has been removed from the list.")
322    {
 
323  1 toggle public Object invoke(final Invocation invoc)
324    {
325  1 final XWikiDocument document = (XWikiDocument) invoc.getParameter(0);
326  1 Assert.assertTrue("Attachment was not removed from the list.",
327    document.getAttachmentList().size() == 0);
328  1 return null;
329    }
330    });
331    }
332    });
333  1 this.createFile();
334   
335  1 this.attachStore.deleteXWikiAttachment(this.mockAttach, true, this.mockContext, false);
336    }
337   
 
338  1 toggle @Test
339    public void documentUpdateOnSaveTest() throws Exception
340    {
341  1 getMockery().checking(new Expectations()
342    {
 
343  1 toggle {
344  1 oneOf(mockHibernate).saveXWikiDoc(doc, mockContext, false);
345  1 oneOf(mockAttachVersionStore).saveArchive(mockArchive, mockContext, false);
346   
347    }
348    });
349   
350  1 this.attachStore.saveAttachmentContent(this.mockAttach, true, this.mockContext, false);
351    }
352   
353    /* -------------------- Helpers -------------------- */
354   
 
355  2 toggle private void createFile() throws IOException
356    {
357  2 this.storeFile.getParentFile().mkdirs();
358  2 OutputStream os = new FileOutputStream(this.storeFile, false);
359  2 IOUtils.copy(HELLO_STREAM, os);
360  2 os.close();
361  2 Assert.assertTrue("The attachment file not created for the test.", this.storeFile.exists());
362    }
363   
 
364  58 toggle private static void resursiveDelete(final File toDelete) throws IOException
365    {
366  58 if (toDelete == null || !toDelete.exists()) {
367  0 return;
368    }
369  58 if (toDelete.isDirectory()) {
370  54 final File[] children = toDelete.listFiles();
371  106 for (int i = 0; i < children.length; i++) {
372  52 resursiveDelete(children[i]);
373    }
374    }
375  58 toDelete.delete();
376    }
377    }