1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package org.xwiki.platform.svg.internal; |
21 |
|
|
22 |
|
import java.io.ByteArrayOutputStream; |
23 |
|
import java.io.File; |
24 |
|
import java.io.FileInputStream; |
25 |
|
import java.io.FileOutputStream; |
26 |
|
import java.io.IOException; |
27 |
|
import java.io.InputStream; |
28 |
|
import java.io.OutputStream; |
29 |
|
import java.util.Arrays; |
30 |
|
|
31 |
|
import javax.servlet.ServletOutputStream; |
32 |
|
import javax.servlet.http.HttpServletResponse; |
33 |
|
|
34 |
|
import org.apache.commons.io.FileUtils; |
35 |
|
import org.apache.commons.io.IOUtils; |
36 |
|
import org.junit.Assert; |
37 |
|
import org.junit.Before; |
38 |
|
import org.junit.Rule; |
39 |
|
import org.junit.Test; |
40 |
|
import org.junit.rules.TemporaryFolder; |
41 |
|
import org.mockito.Mock; |
42 |
|
import org.mockito.Mockito; |
43 |
|
import org.mockito.MockitoAnnotations; |
44 |
|
import org.xwiki.container.Container; |
45 |
|
import org.xwiki.container.Response; |
46 |
|
import org.xwiki.container.servlet.ServletResponse; |
47 |
|
import org.xwiki.model.reference.DocumentReference; |
48 |
|
import org.xwiki.model.reference.DocumentReferenceResolver; |
49 |
|
import org.xwiki.platform.svg.SVGRasterizer; |
50 |
|
import org.xwiki.resource.temporary.TemporaryResourceReference; |
51 |
|
import org.xwiki.resource.temporary.TemporaryResourceStore; |
52 |
|
import org.xwiki.test.mockito.MockitoComponentMockingRule; |
53 |
|
|
54 |
|
import static org.mockito.Mockito.*; |
55 |
|
|
56 |
|
|
57 |
|
@link |
58 |
|
|
59 |
|
@version |
60 |
|
@since |
61 |
|
|
|
|
| 96.5% |
Uncovered Elements: 4 (115) |
Complexity: 27 |
Complexity Density: 0.28 |
|
62 |
|
public class BatikSVGRasterizerTest |
63 |
|
{ |
64 |
|
private static final String VALID_SVG = |
65 |
|
"<svg xmlns='http://www.w3.org/2000/svg'><ellipse cx='50' cy='100' rx='25' ry='50'/></svg>"; |
66 |
|
|
67 |
|
private static final String INVALID_SVG = "<bad>svg!"; |
68 |
|
|
69 |
|
private static final String RASTER_FILE_NAME = Math.abs(VALID_SVG.hashCode()) + ".png"; |
70 |
|
|
71 |
|
@Rule |
72 |
|
public final MockitoComponentMockingRule<SVGRasterizer> mocker = |
73 |
|
new MockitoComponentMockingRule<SVGRasterizer>(BatikSVGRasterizer.class); |
74 |
|
|
75 |
|
@Rule |
76 |
|
public final TemporaryFolder baseDirectory = new TemporaryFolder(); |
77 |
|
|
78 |
|
private DocumentReference dref = new DocumentReference("wiki", "Space", "Document"); |
79 |
|
|
80 |
|
private TemporaryResourceStore temporaryResourceStore; |
81 |
|
|
82 |
|
private DocumentReferenceResolver<String> resolver; |
83 |
|
|
84 |
|
private Container container; |
85 |
|
|
86 |
|
@Mock |
87 |
|
private ServletResponse sresponse; |
88 |
|
|
89 |
|
@Mock |
90 |
|
private HttpServletResponse hsresponse; |
91 |
|
|
92 |
|
private File rasterFile; |
93 |
|
|
94 |
|
private File temporaryFile; |
95 |
|
|
96 |
|
private String temporaryFilePath; |
97 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (21) |
Complexity: 1 |
Complexity Density: 0.05 |
|
98 |
13 |
@Before... |
99 |
|
public void setup() throws Exception |
100 |
|
{ |
101 |
13 |
MockitoAnnotations.initMocks(this); |
102 |
13 |
this.rasterFile = new File(this.baseDirectory.getRoot() + "/temp/svg/wiki/Space/Document/" + RASTER_FILE_NAME); |
103 |
13 |
this.temporaryFile = new File(this.baseDirectory.getRoot() + "/temp/svg/" + RASTER_FILE_NAME); |
104 |
13 |
this.temporaryFilePath = this.temporaryFile.getAbsolutePath(); |
105 |
|
|
106 |
13 |
this.temporaryResourceStore = this.mocker.getInstance(TemporaryResourceStore.class); |
107 |
|
|
108 |
13 |
TemporaryResourceReference rasterFileReferece = new TemporaryResourceReference("svg", RASTER_FILE_NAME, dref); |
109 |
13 |
when(this.temporaryResourceStore.getTemporaryFile(rasterFileReferece)).thenReturn(rasterFile); |
110 |
|
|
111 |
13 |
TemporaryResourceReference temporaryFileReferece = |
112 |
|
new TemporaryResourceReference("svg", RASTER_FILE_NAME, null); |
113 |
13 |
when(this.temporaryResourceStore.getTemporaryFile(temporaryFileReferece)).thenReturn(temporaryFile); |
114 |
|
|
115 |
13 |
String invalidRasterFileName = Math.abs(INVALID_SVG.hashCode()) + ".png"; |
116 |
13 |
File invalidRasterFile = |
117 |
|
new File(this.baseDirectory.getRoot() + "/temp/svg/wiki/Space/Document/" + invalidRasterFileName); |
118 |
13 |
File invalidTemporaryFile = new File(this.baseDirectory.getRoot() + "/temp/svg/" + invalidRasterFileName); |
119 |
|
|
120 |
13 |
TemporaryResourceReference invalidRasterFileReferece = |
121 |
|
new TemporaryResourceReference("svg", invalidRasterFileName, dref); |
122 |
13 |
when(this.temporaryResourceStore.getTemporaryFile(invalidRasterFileReferece)).thenReturn(invalidRasterFile); |
123 |
|
|
124 |
13 |
TemporaryResourceReference invalidTemporaryFileReferece = |
125 |
|
new TemporaryResourceReference("svg", invalidRasterFileName, null); |
126 |
13 |
when(this.temporaryResourceStore.getTemporaryFile(invalidTemporaryFileReferece)) |
127 |
|
.thenReturn(invalidTemporaryFile); |
128 |
|
|
129 |
13 |
this.resolver = this.mocker.getInstance(DocumentReferenceResolver.TYPE_STRING, "current"); |
130 |
13 |
when(this.resolver.resolve("")).thenReturn(this.dref); |
131 |
|
|
132 |
13 |
this.container = this.mocker.getInstance(Container.class); |
133 |
13 |
when(this.container.getResponse()).thenReturn(this.sresponse); |
134 |
13 |
when(this.sresponse.getHttpServletResponse()).thenReturn(this.hsresponse); |
135 |
|
} |
136 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
137 |
1 |
@Test... |
138 |
|
public void rasterizeToTemporaryFileCreatesTemporaryFile() throws Exception |
139 |
|
{ |
140 |
1 |
File tfile = this.mocker.getComponentUnderTest().rasterizeToTemporaryFile(VALID_SVG, 100, 200); |
141 |
1 |
Assert.assertEquals(this.temporaryFilePath, tfile.getAbsolutePath()); |
142 |
1 |
Assert.assertTrue(tfile.exists()); |
143 |
1 |
Assert.assertTrue(isPNG(tfile)); |
144 |
|
} |
145 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
146 |
1 |
@Test... |
147 |
|
public void rasterizeToTemporaryFileReusesFile() throws Exception |
148 |
|
{ |
149 |
1 |
writeTestFile(this.temporaryFile); |
150 |
1 |
File tfile = this.mocker.getComponentUnderTest().rasterizeToTemporaryFile(VALID_SVG, 100, 200); |
151 |
1 |
Assert.assertEquals(this.temporaryFilePath, tfile.getAbsolutePath()); |
152 |
1 |
Assert.assertTrue(tfile.exists()); |
153 |
1 |
Assert.assertTrue(isTestFile(tfile)); |
154 |
|
} |
155 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0.5 |
1PASS
|
|
156 |
1 |
@Test... |
157 |
|
public void rasterizeToTemporaryFileReturnsNullOnExceptions() throws Exception |
158 |
|
{ |
159 |
1 |
File tfile = this.mocker.getComponentUnderTest().rasterizeToTemporaryFile(INVALID_SVG, 0, 0); |
160 |
1 |
Assert.assertNull(tfile); |
161 |
|
} |
162 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
163 |
1 |
@Test... |
164 |
|
public void rasterizeToTemporaryFileReturnsNullWhenParentFolderCannotBeCreated() throws Exception |
165 |
|
{ |
166 |
1 |
this.baseDirectory.getRoot().mkdirs(); |
167 |
1 |
writeTestFile(new File(this.baseDirectory.getRoot(), "temp")); |
168 |
1 |
File tfile = this.mocker.getComponentUnderTest().rasterizeToTemporaryFile(VALID_SVG, 100, 200); |
169 |
1 |
Assert.assertNull(tfile); |
170 |
|
} |
171 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
1PASS
|
|
172 |
1 |
@Test... |
173 |
|
public void rasterizeToTemporaryFileThrowsExceptionWhenFileCannotBeCreated() throws Exception |
174 |
|
{ |
175 |
1 |
this.temporaryFile.mkdirs(); |
176 |
1 |
try { |
177 |
1 |
this.mocker.getComponentUnderTest().rasterizeToTemporaryFile(VALID_SVG, 100, 200); |
178 |
0 |
Assert.fail(); |
179 |
|
} catch (IOException e) { |
180 |
|
|
181 |
|
} |
182 |
|
} |
183 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
184 |
1 |
@Test... |
185 |
|
public void rasterizeToTemporaryResourceUsesContextDocument() throws Exception |
186 |
|
{ |
187 |
1 |
TemporaryResourceReference tref = |
188 |
|
this.mocker.getComponentUnderTest().rasterizeToTemporaryResource(VALID_SVG, 100, 200); |
189 |
1 |
Assert.assertEquals("svg", tref.getModuleId()); |
190 |
1 |
Assert.assertTrue(tref.getParameters().isEmpty()); |
191 |
1 |
Assert.assertEquals(this.dref, tref.getOwningEntityReference()); |
192 |
1 |
Assert.assertEquals(RASTER_FILE_NAME, tref.getResourceName()); |
193 |
|
} |
194 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (7) |
Complexity: 1 |
Complexity Density: 0.14 |
1PASS
|
|
195 |
1 |
@Test... |
196 |
|
public void rasterizeToTemporaryResourceReusesFile() throws Exception |
197 |
|
{ |
198 |
1 |
writeTestFile(this.rasterFile); |
199 |
1 |
TemporaryResourceReference tref = |
200 |
|
this.mocker.getComponentUnderTest().rasterizeToTemporaryResource(VALID_SVG, 100, 200); |
201 |
1 |
Assert.assertEquals("svg", tref.getModuleId()); |
202 |
1 |
Assert.assertTrue(tref.getParameters().isEmpty()); |
203 |
1 |
Assert.assertEquals(this.dref, tref.getOwningEntityReference()); |
204 |
1 |
Assert.assertEquals(Math.abs(VALID_SVG.hashCode()) + ".png", tref.getResourceName()); |
205 |
1 |
Assert.assertTrue(isTestFile(this.rasterFile)); |
206 |
|
} |
207 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0.5 |
1PASS
|
|
208 |
1 |
@Test... |
209 |
|
public void rasterizeToTemporaryResourceReturnsNullOnExceptions() throws Exception |
210 |
|
{ |
211 |
1 |
TemporaryResourceReference tref = |
212 |
|
this.mocker.getComponentUnderTest().rasterizeToTemporaryResource(INVALID_SVG, 0, 0); |
213 |
1 |
Assert.assertNull(tref); |
214 |
|
} |
215 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
216 |
1 |
@Test... |
217 |
|
public void rasterizeToTemporaryResourceReturnsNullWhenBaseTempDirCannotBeCreated() throws Exception |
218 |
|
{ |
219 |
1 |
this.baseDirectory.getRoot().mkdirs(); |
220 |
1 |
writeTestFile(new File(this.baseDirectory.getRoot(), "temp")); |
221 |
1 |
TemporaryResourceReference tref = |
222 |
|
this.mocker.getComponentUnderTest().rasterizeToTemporaryResource(VALID_SVG, 100, 200); |
223 |
1 |
Assert.assertNull(tref); |
224 |
|
} |
225 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
226 |
1 |
@Test... |
227 |
|
public void rasterizeToTemporaryResourceReturnsNullWhenContextTempDirCannotBeCreated() throws Exception |
228 |
|
{ |
229 |
1 |
this.baseDirectory.getRoot().mkdirs(); |
230 |
1 |
writeTestFile( |
231 |
|
new File(new File(new File(new File(this.baseDirectory.getRoot(), "temp"), "svg"), "wiki"), "Space")); |
232 |
1 |
TemporaryResourceReference tref = |
233 |
|
this.mocker.getComponentUnderTest().rasterizeToTemporaryResource(VALID_SVG, 100, 200); |
234 |
1 |
Assert.assertNull(tref); |
235 |
|
} |
236 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
237 |
1 |
@Test... |
238 |
|
public void rasterizeToResponseWritesImageToServletOutputStream() throws Exception |
239 |
|
{ |
240 |
1 |
CapturingOutputStream out = new CapturingOutputStream(); |
241 |
1 |
when(this.hsresponse.getOutputStream()).thenReturn(out); |
242 |
1 |
this.mocker.getComponentUnderTest().rasterizeToResponse(VALID_SVG, 100, 200); |
243 |
1 |
Assert.assertTrue(out.out.size() > 0); |
244 |
1 |
Assert.assertArrayEquals("PNG".getBytes("UTF-8"), Arrays.copyOfRange(out.out.toByteArray(), 1, 4)); |
245 |
|
} |
246 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
247 |
1 |
@Test... |
248 |
|
public void rasterizeToResponseDoesNothingIfNotHttpResponse() throws Exception |
249 |
|
{ |
250 |
1 |
Response r = Mockito.mock(Response.class); |
251 |
1 |
when(this.container.getResponse()).thenReturn(r); |
252 |
1 |
this.mocker.getComponentUnderTest().rasterizeToResponse(VALID_SVG, 100, 200); |
253 |
1 |
Mockito.verifyZeroInteractions(r); |
254 |
|
} |
255 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (4) |
Complexity: 1 |
Complexity Density: 0.25 |
1PASS
|
|
256 |
1 |
@Test... |
257 |
|
public void rasterizeToResponseDoesNothingOnExceptions() throws Exception |
258 |
|
{ |
259 |
1 |
CapturingOutputStream out = new CapturingOutputStream(); |
260 |
1 |
when(this.hsresponse.getOutputStream()).thenReturn(out); |
261 |
1 |
this.mocker.getComponentUnderTest().rasterizeToResponse(INVALID_SVG, 0, 0); |
262 |
1 |
Assert.assertEquals(0, out.out.size()); |
263 |
|
} |
264 |
|
|
|
|
| 88.9% |
Uncovered Elements: 1 (9) |
Complexity: 4 |
Complexity Density: 0.44 |
|
265 |
1 |
private boolean isPNG(File file)... |
266 |
|
{ |
267 |
1 |
try (InputStream in = new FileInputStream(file)) { |
268 |
1 |
byte[] expected = "PNG".getBytes("UTF-8"); |
269 |
1 |
byte[] actual = new byte[3]; |
270 |
1 |
in.read(); |
271 |
1 |
Assert.assertEquals(3, in.read(actual, 0, 3)); |
272 |
1 |
Assert.assertArrayEquals(expected, actual); |
273 |
1 |
return true; |
274 |
|
} catch (Exception ex) { |
275 |
0 |
return false; |
276 |
|
} |
277 |
|
} |
278 |
|
|
|
|
| 87.5% |
Uncovered Elements: 1 (8) |
Complexity: 4 |
Complexity Density: 0.5 |
|
279 |
2 |
private boolean isTestFile(File file)... |
280 |
|
{ |
281 |
2 |
try (InputStream in = new FileInputStream(file)) { |
282 |
2 |
byte[] expected = "test".getBytes("UTF-8"); |
283 |
2 |
byte[] actual = new byte[4]; |
284 |
2 |
Assert.assertEquals(4, in.read(actual, 0, 4)); |
285 |
2 |
Assert.assertArrayEquals(expected, actual); |
286 |
2 |
return true; |
287 |
|
} catch (Exception ex) { |
288 |
0 |
return false; |
289 |
|
} |
290 |
|
} |
291 |
|
|
|
|
| 83.3% |
Uncovered Elements: 1 (6) |
Complexity: 4 |
Complexity Density: 0.67 |
|
292 |
5 |
private boolean writeTestFile(File file) throws IOException... |
293 |
|
{ |
294 |
5 |
FileUtils.forceMkdir(file.getParentFile()); |
295 |
5 |
try (OutputStream out = new FileOutputStream(file)) { |
296 |
5 |
IOUtils.write("test".getBytes(), out); |
297 |
5 |
return true; |
298 |
|
} catch (Exception ex) { |
299 |
0 |
return false; |
300 |
|
} |
301 |
|
} |
302 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 1 |
|
303 |
|
private class CapturingOutputStream extends ServletOutputStream |
304 |
|
{ |
305 |
|
private ByteArrayOutputStream out = new ByteArrayOutputStream(); |
306 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
307 |
1319 |
@Override... |
308 |
|
public void write(int b) throws IOException |
309 |
|
{ |
310 |
1319 |
this.out.write(b); |
311 |
|
} |
312 |
|
} |
313 |
|
} |