View Javadoc

1   package com.atlassian.plugin.web.descriptors;
2   
3   import com.atlassian.plugin.Plugin;
4   import com.atlassian.plugin.PluginParseException;
5   import com.atlassian.plugin.web.Condition;
6   import com.atlassian.plugin.web.conditions.ConditionLoadingException;
7   
8   import org.dom4j.Document;
9   import org.dom4j.DocumentException;
10  import org.dom4j.DocumentHelper;
11  import org.junit.Rule;
12  import org.junit.Test;
13  import org.junit.rules.ExpectedException;
14  import org.mockito.Mockito;
15  
16  import static org.junit.Assert.assertEquals;
17  
18  public class TestConditionElementParser
19  {
20      private static final String TYPE_OR = "<conditions type=\"OR\">";
21      private static final String TYPE_AND = "<conditions type=\"AND\">";
22      private static final String TYPE_CLOSE = "</conditions>";
23      private static final String FALSE = "<condition class=\"com.atlassian.plugin.web.conditions.NeverDisplayCondition\" />";
24      private static final String TRUE = "<condition class=\"com.atlassian.plugin.web.conditions.AlwaysDisplayCondition\" />";
25      private static final String NOT_FALSE = "<condition class=\"com.atlassian.plugin.web.conditions.NeverDisplayCondition\" invert=\"true\" />";
26      private static final String NOT_TRUE = "<condition class=\"com.atlassian.plugin.web.conditions.AlwaysDisplayCondition\" invert=\"true\" />";
27  
28      private final ConditionElementParser conditionElementParser = new ConditionElementParser(new ConditionElementParser.ConditionFactory()
29      {
30          public Condition create(String className, Plugin plugin) throws ConditionLoadingException
31          {
32              return new MockWebFragmentHelper().loadCondition(className, plugin);
33          }
34      });
35  
36      @Rule
37      public ExpectedException expectedException = ExpectedException.none();
38  
39      @Test
40      public void testSimple() throws DocumentException, PluginParseException
41      {
42          assertConditions(TRUE, true); //true
43          assertConditions(FALSE, false); //false
44          assertConditions(NOT_TRUE, false); //NOT true = false
45          assertConditions(NOT_FALSE, true); //NOT false = true
46      }
47  
48      @Test
49      public void testAnd() throws DocumentException, PluginParseException
50      {
51          //using the condition elements only (by default they are grouped with AND operator)
52          assertConditions(TRUE + TRUE, true);//true AND true = true
53          assertConditions(TRUE + FALSE, false);//true AND false = false
54          assertConditions(FALSE + TRUE, false);//false AND true = false
55          assertConditions(FALSE + FALSE, false);//false AND false = false
56  
57          //using the conditions element and explicitly specifying the AND operator
58          assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);//true AND true = true
59          assertConditions(TYPE_AND + TRUE + FALSE + TYPE_CLOSE, false);//true AND false = false
60          assertConditions(TYPE_AND + FALSE + TRUE + TYPE_CLOSE, false);//false AND true = false
61          assertConditions(TYPE_AND + FALSE + FALSE + TYPE_CLOSE, false);//false AND false = false
62      }
63  
64      @Test
65      public void testOr() throws DocumentException, PluginParseException
66      {
67          assertConditions(TYPE_OR + TRUE + TRUE + TYPE_CLOSE, true);//true OR true = true
68          assertConditions(TYPE_OR + TRUE + FALSE + TYPE_CLOSE, true);//true OR false = true
69          assertConditions(TYPE_OR + FALSE + TRUE + TYPE_CLOSE, true);//false OR true = true
70          assertConditions(TYPE_OR + FALSE + FALSE + TYPE_CLOSE, false);//false OR false = false
71      }
72  
73      //test nested AND's - normally all nested AND's should be a single AND
74      @Test
75      public void testNestedAnd() throws DocumentException, PluginParseException
76      {
77          //nested AND'ed conditions
78          assertConditions(TYPE_AND +
79                  TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
80                  TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
81                  TYPE_CLOSE, true);//(true AND true) AND (true AND true) = true
82  
83          //same as above but without explicit AND
84          assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
85                  TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);//(true AND true) AND (true AND true) = true
86  
87          assertConditions(TYPE_AND +
88                  TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
89                  TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
90                  TYPE_CLOSE, false);//(true AND true) AND (false AND true) = false
91      }
92  
93      //test nested OR's - normally all nested OR's should be a single OR
94      @Test
95      public void testNestedOr() throws DocumentException, PluginParseException
96      {
97          //nested OR'ed conditions
98          assertConditions(TYPE_OR +
99                  TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
100                 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
101                 TYPE_CLOSE, true);//(false OR false) OR (false OR true) = true
102 
103         assertConditions(TYPE_OR +
104                 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
105                 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
106                 TYPE_CLOSE, false);//(false OR false) OR (false OR false) = false
107     }
108 
109     @Test
110     public void testNestedMix() throws DocumentException, PluginParseException
111     {
112         //AND with nested OR conditions
113         assertConditions(TYPE_AND +
114                 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
115                 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
116                 TYPE_CLOSE, false);//(false OR false) AND (false OR true) = false
117 
118         assertConditions(TYPE_AND +
119                 TYPE_OR + TRUE + FALSE + TYPE_CLOSE +
120                 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
121                 TYPE_CLOSE, true);//(true OR false) AND (false OR true) = true
122 
123         //OR with nested AND conditions
124         assertConditions(TYPE_OR +
125                 TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
126                 TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
127                 TYPE_CLOSE, false);//(false AND false) OR (false AND true) = false
128 
129         assertConditions(TYPE_OR +
130                 TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
131                 TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
132                 TYPE_CLOSE, true);//(false AND false) OR (true AND true) = true
133     }
134 
135     @Test
136     public void testComplex() throws DocumentException, PluginParseException
137     {
138         assertConditions(TRUE +
139                 TYPE_OR +
140                 TYPE_AND +
141                 FALSE + FALSE +
142                 TYPE_CLOSE +
143                 FALSE +
144                 TYPE_AND +
145                 TRUE +
146                 TYPE_OR +
147                 FALSE + TRUE +
148                 TYPE_CLOSE +
149                 TYPE_CLOSE +
150                 TYPE_CLOSE, true);//true AND ((false AND false) OR false OR (true AND (false OR true))) = true
151     }
152 
153     @Test
154     public void testThatClassAttributeIsCheckedFor() throws DocumentException
155     {
156         expectedException.expect(PluginParseException.class);
157         expectedException.expectMessage("Condition element must specify a class attribute");
158         buildConditionFromXml("<condition/>");
159     }
160 
161     private void assertConditions(String conditionElement, boolean expectedResult) throws DocumentException, PluginParseException
162     {
163         Condition condition = buildConditionFromXml(conditionElement);
164         assertEquals(expectedResult, condition.shouldDisplay(null));
165     }
166 
167     private Condition buildConditionFromXml(String conditionElement) throws DocumentException
168     {
169         String rootElement = "<root>" + conditionElement + "</root>";
170         Document document = DocumentHelper.parseText(rootElement);
171 
172         return conditionElementParser.makeConditions(Mockito.mock(Plugin.class), document
173                 .getRootElement(), ConditionElementParser.CompositeType.AND);
174     }
175 }