1   package com.atlassian.plugins.codegen.modules.common.web;
2   
3   import java.util.List;
4   
5   import com.atlassian.plugins.codegen.modules.PluginModuleLocation;
6   import com.atlassian.plugins.codegen.modules.common.AbstractConditionTest;
7   import com.atlassian.plugins.codegen.modules.common.Resource;
8   
9   import org.dom4j.Document;
10  import org.dom4j.Node;
11  import org.junit.Before;
12  import org.junit.Test;
13  
14  import static org.junit.Assert.assertEquals;
15  import static org.junit.Assert.assertNotNull;
16  
17  /**
18   * @since 3.6
19   */
20  public class WebResourceTest extends AbstractConditionTest<WebResourceProperties>
21  {
22      public static final String MODULE_NAME = "Awesome Web Resource";
23      public static final String XPATH_RESOURCE = "/atlassian-plugin/web-resource/resource";
24  
25      @Before
26      public void runGenerator() throws Exception
27      {
28          setCreator(new WebResourceModuleCreator());
29          setModuleLocation(new PluginModuleLocation.Builder(srcDir)
30                  .resourcesDirectory(resourcesDir)
31                  .testDirectory(testDir)
32                  .templateDirectory(templateDir)
33                  .build());
34  
35          setProps(new WebResourceProperties(MODULE_NAME));
36  
37          props.setIncludeExamples(false);
38  
39      }
40  
41      @Test
42      public void moduleIsValid() throws Exception
43      {
44          String xpath = "/atlassian-plugin/web-resource[@name='Awesome Web Resource' and @key='awesome-web-resource' and @i18n-name-key='awesome-web-resource.name']";
45  
46          creator.createModule(moduleLocation, props);
47          Document pluginDoc = getXmlDocument(pluginXml);
48  
49          assertNotNull("valid web-resource not found", pluginDoc.selectSingleNode(xpath));
50      }
51  
52      @Test
53      public void dependenciesAreAdded() throws Exception
54      {
55          Resource resource = new Resource();
56          resource.setName("style.css");
57          resource.setLocation("com/example/plugin/style.css");
58          resource.setType("download");
59  
60          props.getResources()
61                  .add(resource);
62  
63          props.addDependency("jira.web.resources:ajs");
64          props.addDependency("jira.web.resources:jquery");
65  
66          creator.createModule(moduleLocation, props);
67  
68          Document pluginDoc = getXmlDocument(pluginXml);
69  
70          String depXPath = "/atlassian-plugin/web-resource/dependency";
71          List<Node> depList = pluginDoc.selectNodes(depXPath);
72  
73          assertEquals("expected multiple dependencies", 2, depList.size());
74          assertNotNull("missing ajs dependency", pluginDoc.selectSingleNode("/atlassian-plugin/web-resource/dependency[text() = 'jira.web.resources:ajs']"));
75          assertNotNull("missing jquery dependency", pluginDoc.selectSingleNode("/atlassian-plugin/web-resource/dependency[text() = 'jira.web.resources:jquery']"));
76  
77      }
78  
79      @Test
80      public void contextsAreAdded() throws Exception
81      {
82          Resource resource = new Resource();
83          resource.setName("style.css");
84          resource.setLocation("com/example/plugin/style.css");
85          resource.setType("download");
86  
87          props.getResources()
88                  .add(resource);
89  
90          props.addContext("atl.general");
91          props.addContext("atl.userprofile");
92  
93          creator.createModule(moduleLocation, props);
94  
95          Document pluginDoc = getXmlDocument(pluginXml);
96  
97          String contextXPath = "/atlassian-plugin/web-resource/context";
98          List<Node> contextList = pluginDoc.selectNodes(contextXPath);
99  
100         assertEquals("expected multiple dependencies", 2, contextList.size());
101         assertNotNull("missing general context", pluginDoc.selectSingleNode("/atlassian-plugin/web-resource/context[text() = 'atl.general']"));
102         assertNotNull("missing userprofile context", pluginDoc.selectSingleNode("/atlassian-plugin/web-resource/context[text() = 'atl.userprofile']"));
103 
104     }
105 
106     @Test
107     public void singleTransformationWithSingleTransformerAdded() throws Exception
108     {
109         Resource resource = new Resource();
110         resource.setName("style.css");
111         resource.setLocation("com/example/plugin/style.css");
112         resource.setType("download");
113 
114         props.getResources()
115                 .add(resource);
116 
117         WebResourceTransformation transformation = new WebResourceTransformation("txt");
118         transformation.addTransformerKey("template");
119 
120         props.addTransformation(transformation);
121 
122         creator.createModule(moduleLocation, props);
123 
124         Document pluginDoc = getXmlDocument(pluginXml);
125 
126         String transformationXPath = "/atlassian-plugin/web-resource/transformation";
127         String transformerXPath = "transformer";
128 
129         List<Node> transformationList = pluginDoc.selectNodes(transformationXPath);
130 
131         assertEquals("wrong number of transformations", 1, transformationList.size());
132 
133         Node transformationNode = transformationList.get(0);
134         assertEquals("wrong number of transformers", 1, transformationNode.selectNodes(transformerXPath)
135                 .size());
136         assertEquals("wrong transformation extension", "txt", transformationNode.selectSingleNode("@extension")
137                 .getStringValue());
138         assertNotNull("template transformer not found", transformationNode.selectSingleNode("transformer[@key='template']"));
139     }
140 
141     @Test
142     public void singleTransformationWithMultipleTransformersAdded() throws Exception
143     {
144         Resource resource = new Resource();
145         resource.setName("style.css");
146         resource.setLocation("com/example/plugin/style.css");
147         resource.setType("download");
148 
149         props.getResources()
150                 .add(resource);
151 
152         WebResourceTransformation transformation = new WebResourceTransformation("txt");
153         transformation.addTransformerKey("template");
154         transformation.addTransformerKey("prefix");
155 
156         props.addTransformation(transformation);
157 
158         creator.createModule(moduleLocation, props);
159 
160         Document pluginDoc = getXmlDocument(pluginXml);
161 
162         String transformationXPath = "/atlassian-plugin/web-resource/transformation";
163         String transformerXPath = "transformer";
164 
165         List<Node> transformationList = pluginDoc.selectNodes(transformationXPath);
166 
167         assertEquals("wrong number of transformations", 1, transformationList.size());
168 
169         Node transformationNode = transformationList.get(0);
170 
171         assertEquals("wrong number of transformers", 2, transformationNode.selectNodes(transformerXPath)
172                 .size());
173         assertEquals("wrong transformation extension", "txt", transformationNode.selectSingleNode("@extension")
174                 .getStringValue());
175         assertNotNull("template transformer not found", transformationNode.selectSingleNode("transformer[@key='template']"));
176         assertNotNull("prefix transformer not found", transformationNode.selectSingleNode("transformer[@key='prefix']"));
177     }
178 
179     @Test
180     public void multipleTransformationsAdded() throws Exception
181     {
182         Resource resource = new Resource();
183         resource.setName("style.css");
184         resource.setLocation("com/example/plugin/style.css");
185         resource.setType("download");
186 
187         props.getResources()
188                 .add(resource);
189 
190         WebResourceTransformation txtTrans = new WebResourceTransformation("txt");
191         txtTrans.addTransformerKey("template");
192 
193         WebResourceTransformation cssTrans = new WebResourceTransformation("css");
194         cssTrans.addTransformerKey("prefix");
195 
196         props.addTransformation(txtTrans);
197         props.addTransformation(cssTrans);
198 
199         creator.createModule(moduleLocation, props);
200 
201         Document pluginDoc = getXmlDocument(pluginXml);
202 
203         String transformationXPath = "/atlassian-plugin/web-resource/transformation";
204         String transformerXPath = "transformer";
205 
206         List<Node> transformationList = pluginDoc.selectNodes(transformationXPath);
207 
208         assertEquals("wrong number of transformations", 2, transformationList.size());
209 
210         Node txtNode = pluginDoc.selectSingleNode(transformationXPath + "[@extension='txt']");
211         Node cssNode = pluginDoc.selectSingleNode(transformationXPath + "[@extension='css']");
212 
213         assertNotNull("missing txt node", txtNode);
214         assertNotNull("missing css node", cssNode);
215 
216         assertNotNull("template transformer not found", txtNode.selectSingleNode("transformer[@key='template']"));
217         assertNotNull("prefix transformer not found", cssNode.selectSingleNode("transformer[@key='prefix']"));
218     }
219 
220     @Test
221     public void singleResourceAdded() throws Exception
222     {
223         Resource resource = new Resource();
224         resource.setName("style.css");
225         resource.setLocation("com/example/plugin/style.css");
226         resource.setType("download");
227 
228         props.getResources()
229                 .add(resource);
230 
231         creator.createModule(moduleLocation, props);
232 
233         Document pluginDoc = getXmlDocument(pluginXml);
234         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
235 
236         assertEquals("expected single resource", 1, resourceList.size());
237 
238         String nodeXpath = "//resource[@name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
239         assertNotNull("single resource not found", pluginDoc.selectSingleNode(nodeXpath));
240 
241     }
242 
243     @Test
244     public void singleResourceNamePatternAdded() throws Exception
245     {
246         Resource resource = new Resource();
247         resource.setNamePattern("*.css");
248         resource.setLocation("com/example/plugin/style.css");
249         resource.setType("download");
250 
251         props.getResources()
252                 .add(resource);
253 
254         creator.createModule(moduleLocation, props);
255 
256         Document pluginDoc = getXmlDocument(pluginXml);
257         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
258 
259         assertEquals("expected single resource", 1, resourceList.size());
260 
261         String nodeXpath = "//resource[@namePattern='*.css' and @location='com/example/plugin/style.css' and @type='download']";
262         assertNotNull("single resource not found", pluginDoc.selectSingleNode(nodeXpath));
263 
264     }
265 
266     @Test
267     public void nameChosenOverPattern() throws Exception
268     {
269         Resource resource = new Resource();
270         resource.setName("style.css");
271         resource.setNamePattern("*.css");
272         resource.setLocation("com/example/plugin/style.css");
273         resource.setType("download");
274 
275         props.getResources()
276                 .add(resource);
277 
278         creator.createModule(moduleLocation, props);
279 
280         Document pluginDoc = getXmlDocument(pluginXml);
281         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
282 
283         assertEquals("expected single resource", 1, resourceList.size());
284 
285         String nodeXpath = "//resource[not(@namePattern) and @name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
286         assertNotNull("single resource not found", pluginDoc.selectSingleNode(nodeXpath));
287 
288     }
289 
290     @Test
291     public void resourceParamsAdded() throws Exception
292     {
293         Resource resource = new Resource();
294         resource.setName("style.css");
295         resource.setLocation("com/example/plugin/style.css");
296         resource.setType("download");
297         resource.getParams()
298                 .put("content-type", "text/css");
299         resource.getParams()
300                 .put("awesome", "me");
301 
302         props.getResources()
303                 .add(resource);
304 
305         creator.createModule(moduleLocation, props);
306 
307         Document pluginDoc = getXmlDocument(pluginXml);
308         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
309 
310         assertEquals("expected single resource", 1, resourceList.size());
311 
312         String nodeXpath = "//resource[not(@namePattern) and @name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
313         Node resourceNode = pluginDoc.selectSingleNode(nodeXpath);
314 
315         List<Node> paramList = resourceNode.selectNodes(XPATH_PARAM_RELATIVE);
316         assertEquals("expected resource params", 2, paramList.size());
317 
318         assertNotNull("missing content param", resourceNode.selectSingleNode("param[@name='content-type' and @value='text/css']"));
319         assertNotNull("missing awesome param", resourceNode.selectSingleNode("param[@name='awesome' and @value='me']"));
320 
321     }
322 
323     @Test
324     public void nonBatchResourceParamAdded() throws Exception
325     {
326         Resource resource = new Resource();
327         resource.setName("style.css");
328         resource.setLocation("com/example/plugin/style.css");
329         resource.setType("download");
330         resource.setBatch(false);
331 
332         props.getResources()
333                 .add(resource);
334 
335         creator.createModule(moduleLocation, props);
336 
337         Document pluginDoc = getXmlDocument(pluginXml);
338         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
339 
340         assertEquals("expected single resource", 1, resourceList.size());
341 
342         String nodeXpath = "//resource[not(@namePattern) and @name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
343         Node resourceNode = pluginDoc.selectSingleNode(nodeXpath);
344 
345         List<Node> paramList = resourceNode.selectNodes(XPATH_PARAM_RELATIVE);
346         assertEquals("expected resource batch param", 1, paramList.size());
347 
348         assertNotNull("missing batch param", resourceNode.selectSingleNode("param[@name='batch' and @value='false']"));
349 
350     }
351 
352     @Test
353     public void nonBatchResourceWithParamsAdded() throws Exception
354     {
355         Resource resource = new Resource();
356         resource.setName("style.css");
357         resource.setLocation("com/example/plugin/style.css");
358         resource.setType("download");
359         resource.setBatch(false);
360         resource.getParams()
361                 .put("content-type", "text/css");
362         resource.getParams()
363                 .put("awesome", "me");
364 
365         props.getResources()
366                 .add(resource);
367 
368         creator.createModule(moduleLocation, props);
369 
370         Document pluginDoc = getXmlDocument(pluginXml);
371         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
372 
373         assertEquals("expected single resource", 1, resourceList.size());
374 
375         String nodeXpath = "//resource[not(@namePattern) and @name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
376         Node resourceNode = pluginDoc.selectSingleNode(nodeXpath);
377 
378         List<Node> paramList = resourceNode.selectNodes(XPATH_PARAM_RELATIVE);
379         assertEquals("expected resource params", 3, paramList.size());
380 
381         assertNotNull("missing batch param", resourceNode.selectSingleNode("param[@name='batch' and @value='false']"));
382         assertNotNull("missing content param", resourceNode.selectSingleNode("param[@name='content-type' and @value='text/css']"));
383         assertNotNull("missing awesome param", resourceNode.selectSingleNode("param[@name='awesome' and @value='me']"));
384 
385     }
386 
387     @Test
388     public void multipleResourcesAdded() throws Exception
389     {
390         Resource resource = new Resource();
391         resource.setName("style.css");
392         resource.setLocation("com/example/plugin/style.css");
393         resource.setType("download");
394         resource.getParams()
395                 .put("content-type", "text/css");
396         resource.getParams()
397                 .put("awesome", "me");
398 
399         Resource resource2 = new Resource();
400         resource2.setName("custom.js");
401         resource2.setLocation("com/example/plugin/custom.js");
402         resource2.setType("download");
403 
404         props.getResources()
405                 .add(resource);
406         props.getResources()
407                 .add(resource2);
408 
409         creator.createModule(moduleLocation, props);
410 
411         Document pluginDoc = getXmlDocument(pluginXml);
412         List<Node> resourceList = pluginDoc.selectNodes(XPATH_RESOURCE);
413 
414         assertEquals("expected multiple resources", 2, resourceList.size());
415 
416         String nodeXpath = "//resource[not(@namePattern) and @name='style.css' and @location='com/example/plugin/style.css' and @type='download']";
417         String node2Xpath = "//resource[not(@namePattern) and @name='custom.js' and @location='com/example/plugin/custom.js' and @type='download']";
418 
419         assertNotNull("missing css resource", pluginDoc.selectSingleNode(nodeXpath));
420         assertNotNull("missing js resource", pluginDoc.selectSingleNode(node2Xpath));
421 
422     }
423 
424 }