1   package com.atlassian.plugins.codegen.modules.common;
2   
3   import java.util.List;
4   
5   import com.atlassian.plugins.codegen.AbstractCodegenTestCase;
6   import com.atlassian.plugins.codegen.modules.common.web.AbstractConditionsProperties;
7   
8   import org.dom4j.Document;
9   import org.dom4j.Node;
10  import org.junit.Test;
11  
12  import static org.junit.Assert.*;
13  
14  /**
15   * @since 3.6
16   */
17  public abstract class AbstractConditionTest<T extends AbstractConditionsProperties> extends AbstractCodegenTestCase<T>
18  {
19      public static final String XPATH_ALL_CONDITIONS = "//conditions";
20      public static final String XPATH_TOP_CONDITIONS = "/atlassian-plugin/*[not(self::conditions)]/conditions";
21      public static final String XPATH_CONDITIONS_RELATIVE = "conditions";
22      public static final String XPATH_ALL_CONDITION = "//condition";
23      public static final String XPATH_TOP_CONDITION = "/atlassian-plugin/*[not(self::conditions)]/condition";
24      public static final String XPATH_CONDITION_RELATIVE = "condition";
25      public static final String JIRA_GLOBAL_PERMISSION = "com.atlassian.jira.plugin.webfragment.conditions.JiraGlobalPermissionCondition";
26      public static final String JIRA_HAS_ISSUE_PERMISSION = "com.atlassian.jira.plugin.webfragment.conditions.HasIssuePermissionCondition";
27      public static final String XPATH_PARAM_RELATIVE = "param";
28  
29      @Test
30      public void emptyConditionsAreNotIncluded() throws Exception
31      {
32          creator.createModule(moduleLocation, props);
33          Document pluginDoc = getXmlDocument(pluginXml);
34          List<Node> conditions = pluginDoc.selectNodes(XPATH_ALL_CONDITIONS);
35          List<Node> condition = pluginDoc.selectNodes(XPATH_ALL_CONDITION);
36  
37          assertTrue("found conditions but should be empty", conditions.isEmpty());
38          assertTrue("found single condition but should be empty", condition.isEmpty());
39      }
40  
41      @Test
42      public void singleConditionWithoutParamsAdded() throws Exception
43      {
44          props.getConditions()
45                  .add(new Condition(JIRA_GLOBAL_PERMISSION));
46          creator.createModule(moduleLocation, props);
47  
48          Document pluginDoc = getXmlDocument(pluginXml);
49          List<Node> conditions = pluginDoc.selectNodes(XPATH_ALL_CONDITIONS);
50  
51          assertTrue("conditions found but should be single", conditions.isEmpty());
52  
53          List<Node> condition = pluginDoc.selectNodes(XPATH_ALL_CONDITION);
54  
55          assertEquals("single condition not found", 1, condition.size());
56  
57          Node conditionNode = condition.get(0);
58          assertEquals("class name mismatch", JIRA_GLOBAL_PERMISSION, conditionNode.selectSingleNode("@class")
59                  .getStringValue());
60          assertNull("should not be inverted", conditionNode.selectSingleNode("@invert"));
61      }
62  
63      @Test
64      public void invertedConditionHasAttribute() throws Exception
65      {
66          Condition jiraCondition = new Condition(JIRA_GLOBAL_PERMISSION);
67          jiraCondition.setInvert(true);
68  
69          props.getConditions()
70                  .add(jiraCondition);
71          creator.createModule(moduleLocation, props);
72  
73          Document pluginDoc = getXmlDocument(pluginXml);
74  
75          List<Node> condition = pluginDoc.selectNodes(XPATH_ALL_CONDITION);
76  
77          assertEquals("single condition not found", 1, condition.size());
78  
79          Node conditionNode = condition.get(0);
80          assertEquals("class name mismatch", JIRA_GLOBAL_PERMISSION, conditionNode.selectSingleNode("@class")
81                  .getStringValue());
82          assertEquals("should be inverted", "true", conditionNode.selectSingleNode("@invert")
83                  .getStringValue());
84      }
85  
86      @Test
87      public void singleANDConditionsAdded() throws Exception
88      {
89          Conditions conditionsRoot = new Conditions(Conditions.AND);
90          conditionsRoot.addCondition(new Condition(JIRA_GLOBAL_PERMISSION));
91  
92          props.getConditions()
93                  .add(conditionsRoot);
94  
95          creator.createModule(moduleLocation, props);
96  
97          Document pluginDoc = getXmlDocument(pluginXml);
98          List<Node> conditions = pluginDoc.selectNodes(XPATH_ALL_CONDITIONS);
99  
100         assertEquals("conditions not found", 1, conditions.size());
101 
102         Node conditionsNode = conditions.get(0);
103 
104         assertEquals("wrong conditions type", Conditions.AND, conditionsNode.selectSingleNode("@type")
105                 .getStringValue());
106 
107         List<Node> condition = conditionsNode.selectNodes(XPATH_CONDITION_RELATIVE);
108 
109         assertEquals("single AND condition not found", 1, condition.size());
110 
111         Node conditionNode = condition.get(0);
112         assertEquals("class name mismatch", JIRA_GLOBAL_PERMISSION, conditionNode.selectSingleNode("@class")
113                 .getStringValue());
114         assertNull("should not be inverted", conditionNode.selectSingleNode("@invert"));
115     }
116 
117     @Test
118     public void singleORConditionsAdded() throws Exception
119     {
120         Conditions conditionsRoot = new Conditions(Conditions.OR);
121         conditionsRoot.addCondition(new Condition(JIRA_GLOBAL_PERMISSION));
122 
123         props.getConditions()
124                 .add(conditionsRoot);
125 
126         creator.createModule(moduleLocation, props);
127 
128         Document pluginDoc = getXmlDocument(pluginXml);
129         List<Node> conditions = pluginDoc.selectNodes(XPATH_ALL_CONDITIONS);
130 
131         assertEquals("conditions not found", 1, conditions.size());
132 
133         Node conditionsNode = conditions.get(0);
134 
135         assertEquals("wrong conditions type", Conditions.OR, conditionsNode.selectSingleNode("@type")
136                 .getStringValue());
137 
138         List<Node> condition = conditionsNode.selectNodes(XPATH_CONDITION_RELATIVE);
139 
140         assertEquals("single AND condition not found", 1, condition.size());
141 
142         Node conditionNode = condition.get(0);
143         assertEquals("class name mismatch", JIRA_GLOBAL_PERMISSION, conditionNode.selectSingleNode("@class")
144                 .getStringValue());
145         assertNull("should not be inverted", conditionNode.selectSingleNode("@invert"));
146     }
147 
148     @Test
149     public void nestedMixedConditionsAdded() throws Exception
150     {
151         Conditions conditionsRoot = new Conditions(Conditions.AND);
152         conditionsRoot.addCondition(new Condition(JIRA_GLOBAL_PERMISSION));
153 
154         Conditions nestedConditions = new Conditions(Conditions.OR);
155         nestedConditions.addCondition(new Condition(JIRA_HAS_ISSUE_PERMISSION));
156 
157         conditionsRoot.addCondition(nestedConditions);
158         props.getConditions()
159                 .add(conditionsRoot);
160 
161         creator.createModule(moduleLocation, props);
162 
163         Document pluginDoc = getXmlDocument(pluginXml);
164         List<Node> conditionsList = pluginDoc.selectNodes(XPATH_TOP_CONDITIONS);
165 
166         assertEquals("conditions not found", 1, conditionsList.size());
167 
168         Node conditionsNode = conditionsList.get(0);
169 
170         assertEquals("wrong conditions type", Conditions.AND, conditionsNode.selectSingleNode("@type")
171                 .getStringValue());
172 
173         List<Node> firstSingleList = conditionsNode.selectNodes(XPATH_CONDITION_RELATIVE);
174 
175         assertEquals("first single condition not found", 1, firstSingleList.size());
176 
177         Node firstSingleNode = firstSingleList.get(0);
178         assertEquals("first single class name mismatch", JIRA_GLOBAL_PERMISSION, firstSingleNode.selectSingleNode("@class")
179                 .getStringValue());
180 
181         List<Node> nestedConditionsList = conditionsNode.selectNodes(XPATH_CONDITIONS_RELATIVE);
182 
183         assertEquals("nested conditions not found", 1, nestedConditionsList.size());
184 
185         Node nestedConditionsNode = nestedConditionsList.get(0);
186 
187         assertEquals("wrong nested conditions type", Conditions.OR, nestedConditionsNode.selectSingleNode("@type")
188                 .getStringValue());
189 
190         List<Node> nestedConditionList = nestedConditionsNode.selectNodes(XPATH_CONDITION_RELATIVE);
191 
192         assertEquals("nested condition not found", 1, nestedConditionList.size());
193 
194         Node nestedConditionNode = nestedConditionList.get(0);
195 
196         assertEquals("nested condition class name mismatch", JIRA_HAS_ISSUE_PERMISSION, nestedConditionNode.selectSingleNode("@class")
197                 .getStringValue());
198         assertNull("should not be inverted", nestedConditionNode.selectSingleNode("@invert"));
199     }
200 
201     @Test
202     public void conditionIsSiblingOfConditions() throws Exception
203     {
204         Conditions conditionsRoot = new Conditions(Conditions.AND);
205         conditionsRoot.addCondition(new Condition(JIRA_GLOBAL_PERMISSION));
206 
207         Condition singleCondition = new Condition(JIRA_HAS_ISSUE_PERMISSION);
208 
209         props.getConditions()
210                 .add(conditionsRoot);
211         props.getConditions()
212                 .add(singleCondition);
213 
214         creator.createModule(moduleLocation, props);
215 
216         Document pluginDoc = getXmlDocument(pluginXml);
217         List<Node> conditionsList = pluginDoc.selectNodes(XPATH_TOP_CONDITIONS);
218 
219         assertEquals("conditions not found", 1, conditionsList.size());
220 
221         Node conditionsNode = conditionsList.get(0);
222 
223         assertEquals("wrong conditions type", Conditions.AND, conditionsNode.selectSingleNode("@type")
224                 .getStringValue());
225 
226         List<Node> nestedSingleList = conditionsNode.selectNodes(XPATH_CONDITION_RELATIVE);
227 
228         assertEquals("nested single condition not found", 1, nestedSingleList.size());
229 
230         Node nestedSingleNode = nestedSingleList.get(0);
231         assertEquals("nested single class name mismatch", JIRA_GLOBAL_PERMISSION, nestedSingleNode.selectSingleNode("@class")
232                 .getStringValue());
233 
234         List<Node> siblingConditionList = pluginDoc.selectNodes(XPATH_TOP_CONDITION);
235 
236         assertEquals("sibling condition not found", 1, siblingConditionList.size());
237 
238         Node siblingNode = siblingConditionList.get(0);
239 
240         assertEquals("sibling condition class name mismatch", JIRA_HAS_ISSUE_PERMISSION, siblingNode.selectSingleNode("@class")
241                 .getStringValue());
242         assertNull("should not be inverted", siblingNode.selectSingleNode("@invert"));
243     }
244 
245     @Test
246     public void conditionParamsAreRendered() throws Exception
247     {
248         Condition condition = new Condition(JIRA_GLOBAL_PERMISSION);
249         condition.getParams()
250                 .put("permission", "admin");
251         condition.getParams()
252                 .put("username", "user");
253 
254         props.getConditions()
255                 .add(condition);
256 
257         creator.createModule(moduleLocation, props);
258 
259         Document pluginDoc = getXmlDocument(pluginXml);
260         List<Node> conditionList = pluginDoc.selectNodes(XPATH_ALL_CONDITION);
261 
262         assertEquals("wrong number of conditions", 1, conditionList.size());
263 
264         Node conditionNode = conditionList.get(0);
265         List<Node> paramsList = conditionNode.selectNodes(XPATH_PARAM_RELATIVE);
266 
267         assertEquals("wrong number of params", 2, paramsList.size());
268 
269         Node permissionParam = conditionNode.selectSingleNode("param[@name='permission' and @value='admin']");
270         Node usernameParam = conditionNode.selectSingleNode("param[@name='username' and @value='user']");
271 
272         assertNotNull("permission param not found", permissionParam);
273         assertNotNull("username param not found", usernameParam);
274     }
275 }