1   package com.atlassian.maven.plugins.amps.util;
2   
3   import org.apache.commons.io.FileUtils;
4   import org.junit.After;
5   import org.junit.Before;
6   import org.junit.Test;
7   
8   import java.io.File;
9   import java.io.IOException;
10  import java.util.Enumeration;
11  import java.util.UUID;
12  import java.util.zip.ZipEntry;
13  import java.util.zip.ZipFile;
14  
15  import static org.hamcrest.core.IsEqual.equalTo;
16  import static org.hamcrest.core.IsNot.not;
17  import static org.junit.Assert.assertEquals;
18  import static org.junit.Assert.assertThat;
19  import static org.junit.Assert.assertTrue;
20  
21  public class TestZipUtils
22  {
23      public static final int NUM_FILES = 2;
24      public static final int NUM_FOLDERS = 4;
25      public static final int NUM_FOLDERS_NESTED_PREFIX = NUM_FOLDERS + 1;
26  
27      public static final String ROOT_DIR = "test-zip-dir";
28      public static final String FIRST_PREFIX = "prefix1";
29      public static final String SECOND_PREFIX = "prefix2";
30      public static final String NESTED_PREFIX = FIRST_PREFIX + "/" + SECOND_PREFIX;
31  
32      private File tempDir;
33      private File sourceZipDir;
34      private ZipFile zip;
35  
36      @Before
37      public void ensureDirsExist() throws IOException
38      {
39  
40          //Create the temp dir
41          final File sysTempDir = new File(System.getProperty("java.io.tmpdir"));
42          String dirName = UUID.randomUUID().toString();
43          tempDir = new File(sysTempDir, dirName);
44          tempDir.mkdirs();
45  
46          //Create our test source tree
47          sourceZipDir = new File(tempDir,ROOT_DIR);
48          File level2sub1 = new File(sourceZipDir, "level2sub1");
49          File level2sub2 = new File(sourceZipDir, "level2sub2");
50          File level3sub1 = new File(level2sub2, "level3sub1");
51  
52          File level2TextFile = new File(level2sub2,"level2sub2.txt");
53          File level3TextFile = new File(level3sub1,"level3sub1.txt");
54  
55          level2sub1.mkdirs();
56          level3sub1.mkdirs();
57  
58          FileUtils.writeStringToFile(level2TextFile,"level2sub2");
59          FileUtils.writeStringToFile(level3TextFile,"level3sub1");
60      }
61  
62  
63      @After
64      public void removeTempDir() throws IOException
65      {
66          //make sure zip is closed, else delete fails on windows
67          if (zip != null) {
68              try {
69                  zip.close();
70              } catch (IOException e) {
71                  //ignore
72              }
73              zip = null;
74          }
75          FileUtils.deleteDirectory(tempDir);
76      }
77  
78      @Test
79      public void zipContainsSinglePrefix() throws IOException
80      {
81          File zipFile = new File(tempDir,"zip-with-prefix.zip");
82          ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
83  
84          zip = new ZipFile(zipFile);
85          final Enumeration<? extends ZipEntry> entries = zip.entries();
86  
87          while (entries.hasMoreElements())
88          {
89              final ZipEntry zipEntry = entries.nextElement();
90              String zipPath = zipEntry.getName();
91              String testPrefix = zipPath.substring(0,zipPath.indexOf("/"));
92  
93              assertEquals(FIRST_PREFIX,testPrefix);
94          }
95      }
96  
97      @Test
98      public void zipContainsNestedPrefix() throws IOException
99      {
100         File zipFile = new File(tempDir,"zip-nested-prefix.zip");
101         ZipUtils.zipDir(zipFile,sourceZipDir,NESTED_PREFIX);
102 
103         zip = new ZipFile(zipFile);
104         final Enumeration<? extends ZipEntry> entries = zip.entries();
105 
106         while (entries.hasMoreElements())
107         {
108             final ZipEntry zipEntry = entries.nextElement();
109             String zipPath = zipEntry.getName();
110             String[] segments = zipPath.split("/");
111             if(segments.length > 1) {
112                 String testPrefix = segments[0] + "/" + segments[1];
113 
114                 assertEquals(NESTED_PREFIX,testPrefix);
115             }
116         }
117     }
118 
119     @Test
120     public void prefixedZipDoesNotContainRootDir() throws IOException
121     {
122         File zipFile = new File(tempDir,"zip-with-prefix-no-root.zip");
123         ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
124 
125         zip = new ZipFile(zipFile);
126         final Enumeration<? extends ZipEntry> entries = zip.entries();
127 
128         while (entries.hasMoreElements())
129         {
130             final ZipEntry zipEntry = entries.nextElement();
131             String zipPath = zipEntry.getName();
132             String[] segments = zipPath.split("/");
133             if(segments.length > 1) {
134                 String rootPath = segments[1];
135 
136                 assertThat(rootPath, not(equalTo(ROOT_DIR)));
137             }
138         }
139     }
140 
141     @Test
142     public void nestedPrefixedZipDoesNotContainRootDir() throws IOException
143     {
144         File zipFile = new File(tempDir,"zip-nested-prefix-no-root.zip");
145         ZipUtils.zipDir(zipFile,sourceZipDir,NESTED_PREFIX);
146 
147         zip = new ZipFile(zipFile);
148         final Enumeration<? extends ZipEntry> entries = zip.entries();
149 
150         while (entries.hasMoreElements())
151         {
152             final ZipEntry zipEntry = entries.nextElement();
153             String zipPath = zipEntry.getName();
154             String[] segments = zipPath.split("/");
155             if(segments.length > 2) {
156                 String rootPath = segments[2];
157 
158                 assertThat(rootPath, not(equalTo(ROOT_DIR)));
159             }
160         }
161     }
162 
163     @Test
164     public void emptyPrefixedZipContainsRootDir() throws IOException
165     {
166         File zipFile = new File(tempDir,"zip-empty-prefix.zip");
167         ZipUtils.zipDir(zipFile,sourceZipDir,"");
168 
169         zip = new ZipFile(zipFile);
170         final Enumeration<? extends ZipEntry> entries = zip.entries();
171 
172         while (entries.hasMoreElements())
173         {
174             final ZipEntry zipEntry = entries.nextElement();
175             String zipPath = zipEntry.getName();
176             String rootPath = zipPath.substring(0,zipPath.indexOf("/"));
177 
178             assertEquals(ROOT_DIR,rootPath);
179         }
180     }
181 
182     @Test
183     public void nullPrefixedZipContainsRootDir() throws IOException
184     {
185         File zipFile = new File(tempDir,"zip-null-prefix.zip");
186         ZipUtils.zipDir(zipFile,sourceZipDir,null);
187 
188         zip = new ZipFile(zipFile);
189         final Enumeration<? extends ZipEntry> entries = zip.entries();
190 
191         while (entries.hasMoreElements())
192         {
193             final ZipEntry zipEntry = entries.nextElement();
194             String zipPath = zipEntry.getName();
195             String rootPath = zipPath.substring(0,zipPath.indexOf("/"));
196 
197             assertEquals(ROOT_DIR,rootPath);
198         }
199     }
200 
201     @Test
202     public void emptyPrefixedZipFolderCountMatches() throws IOException
203     {
204         File zipFile = new File(tempDir,"zip-empty-prefix.zip");
205         ZipUtils.zipDir(zipFile,sourceZipDir,"");
206 
207         zip = new ZipFile(zipFile);
208         final Enumeration<? extends ZipEntry> entries = zip.entries();
209 
210         int numFolders = 0;
211 
212         while (entries.hasMoreElements())
213         {
214             final ZipEntry zipEntry = entries.nextElement();
215             if(zipEntry.isDirectory()) {
216                 numFolders++;
217             }
218         }
219 
220         assertEquals(NUM_FOLDERS,numFolders);
221     }
222 
223     @Test
224     public void singlePrefixedZipFolderCountMatches() throws IOException
225     {
226         File zipFile = new File(tempDir,"zip-single-prefix.zip");
227         ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
228 
229         zip = new ZipFile(zipFile);
230         final Enumeration<? extends ZipEntry> entries = zip.entries();
231 
232         int numFolders = 0;
233 
234         while (entries.hasMoreElements())
235         {
236             final ZipEntry zipEntry = entries.nextElement();
237             if(zipEntry.isDirectory()) {
238                 numFolders++;
239             }
240         }
241 
242         assertEquals(NUM_FOLDERS,numFolders);
243     }
244 
245     @Test
246     public void nestedPrefixedZipFolderCountMatches() throws IOException
247     {
248         File zipFile = new File(tempDir,"zip-nested-prefix.zip");
249         ZipUtils.zipDir(zipFile,sourceZipDir,NESTED_PREFIX);
250 
251         zip = new ZipFile(zipFile);
252         final Enumeration<? extends ZipEntry> entries = zip.entries();
253 
254         int numFolders = 0;
255 
256         while (entries.hasMoreElements())
257         {
258             final ZipEntry zipEntry = entries.nextElement();
259             if(zipEntry.isDirectory()) {
260                 numFolders++;
261             }
262         }
263 
264         assertEquals(NUM_FOLDERS_NESTED_PREFIX,numFolders);
265     }
266 
267     @Test
268     public void zipFileCountMatches() throws IOException
269     {
270         File zipFile = new File(tempDir,"zip-single-prefix.zip");
271         ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
272 
273         zip = new ZipFile(zipFile);
274         final Enumeration<? extends ZipEntry> entries = zip.entries();
275 
276         int numFiles = 0;
277 
278         while (entries.hasMoreElements())
279         {
280             final ZipEntry zipEntry = entries.nextElement();
281             if(!zipEntry.isDirectory()) {
282                 numFiles++;
283             }
284         }
285 
286         assertEquals(NUM_FILES,numFiles);
287     }
288 
289     @Test
290     public void unzipNonPrefixed() throws IOException
291     {
292         File zipFile = new File(tempDir,"zip-empty-prefix.zip");
293         ZipUtils.zipDir(zipFile,sourceZipDir,"");
294 
295         File unzipDir = new File(tempDir,"unzip-empty-prefix");
296         ZipUtils.unzip(zipFile,unzipDir.getAbsolutePath());
297 
298         File rootUnzip = new File(unzipDir,ROOT_DIR);
299 
300         assertTrue("root folder in zip was not unzipped",(rootUnzip.exists() && rootUnzip.isDirectory()));
301     }
302 
303     @Test
304     public void unzipSinglePrefix() throws IOException
305     {
306         File zipFile = new File(tempDir,"zip-single-prefix.zip");
307         ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
308 
309         File unzipDir = new File(tempDir,"unzip-single-prefix");
310         ZipUtils.unzip(zipFile,unzipDir.getAbsolutePath());
311 
312         File rootUnzip = new File(unzipDir,FIRST_PREFIX);
313 
314         assertTrue("single prefix folder in zip was not unzipped",(rootUnzip.exists() && rootUnzip.isDirectory()));
315     }
316 
317     @Test
318     public void unzipNestedPrefix() throws IOException
319     {
320         File zipFile = new File(tempDir,"zip-nested-prefix.zip");
321         ZipUtils.zipDir(zipFile,sourceZipDir,NESTED_PREFIX);
322 
323         File unzipDir = new File(tempDir,"unzip-nested-prefix");
324         ZipUtils.unzip(zipFile,unzipDir.getAbsolutePath());
325 
326         File rootUnzip = new File(unzipDir,FIRST_PREFIX);
327         File nestedUnzip = new File(rootUnzip,SECOND_PREFIX);
328 
329         assertTrue("nested prefix folder in zip was not unzipped",(nestedUnzip.exists() && nestedUnzip.isDirectory()));
330     }
331 
332     @Test
333     public void unzipSinglePrefixTrimmed() throws IOException
334     {
335         File zipFile = new File(tempDir,"zip-single-prefix.zip");
336         ZipUtils.zipDir(zipFile,sourceZipDir,FIRST_PREFIX);
337 
338         File unzipDir = new File(tempDir,"unzip-single-prefix");
339         ZipUtils.unzip(zipFile,unzipDir.getAbsolutePath(),1);
340 
341         File rootUnzip = new File(unzipDir,FIRST_PREFIX);
342 
343         assertTrue("single prefix folder in zip should have been trimmed",!rootUnzip.exists());
344     }
345 
346     @Test
347     public void unzipNestedPrefixTrimmed() throws IOException
348     {
349         File zipFile = new File(tempDir,"zip-nested-prefix.zip");
350         ZipUtils.zipDir(zipFile,sourceZipDir,NESTED_PREFIX);
351 
352         File unzipDir = new File(tempDir,"unzip-nested-prefix");
353         ZipUtils.unzip(zipFile,unzipDir.getAbsolutePath(),2);
354 
355         File nestedUnzip = new File(unzipDir,SECOND_PREFIX);
356 
357         assertTrue("nested prefix folder in zip should have been trimmed",!nestedUnzip.exists());
358     }
359 }