1   package com.atlassian.plugin.web.descriptors;
2   
3   import com.atlassian.plugin.PluginParseException;
4   import com.atlassian.plugin.web.Condition;
5   import junit.framework.TestCase;
6   import org.dom4j.Document;
7   import org.dom4j.DocumentException;
8   import org.dom4j.DocumentHelper;
9   
10  public class TestAbstractWebFragmentModuleDescriptor extends TestCase
11  {
12      private static final String TYPE_OR = "<conditions type=\"OR\">";
13      private static final String TYPE_AND = "<conditions type=\"AND\">";
14      private static final String TYPE_CLOSE = "</conditions>";
15      private static final String FALSE = "<condition class=\"com.atlassian.plugin.web.conditions.NeverDisplayCondition\" />";
16      private static final String TRUE = "<condition class=\"com.atlassian.plugin.web.conditions.AlwaysDisplayCondition\" />";
17      private static final String NOT_FALSE = "<condition class=\"com.atlassian.plugin.web.conditions.NeverDisplayCondition\" invert=\"true\" />";
18      private static final String NOT_TRUE = "<condition class=\"com.atlassian.plugin.web.conditions.AlwaysDisplayCondition\" invert=\"true\" />";
19  
20      private final AbstractWebFragmentModuleDescriptor descriptor = new MockAbstractWebFragmentModuleDescriptor(new MockWebInterfaceManager());
21  
22      public void testSimple() throws DocumentException, PluginParseException
23      {
24          assertConditions(TRUE, true); //true
25          assertConditions(FALSE, false); //false
26          assertConditions(NOT_TRUE, false); //NOT true = false
27          assertConditions(NOT_FALSE, true); //NOT false = true
28      }
29  
30      public void testAnd() throws DocumentException, PluginParseException
31      {
32          //using the condition elements only (by default they are grouped with AND operator)
33          assertConditions(TRUE + TRUE, true);//true AND true = true
34          assertConditions(TRUE + FALSE, false);//true AND false = false
35          assertConditions(FALSE + TRUE, false);//false AND true = false
36          assertConditions(FALSE + FALSE, false);//false AND false = false
37  
38          //using the conditions element and explicitly specifying the AND operator
39          assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);//true AND true = true
40          assertConditions(TYPE_AND + TRUE + FALSE + TYPE_CLOSE, false);//true AND false = false
41          assertConditions(TYPE_AND + FALSE + TRUE + TYPE_CLOSE, false);//false AND true = false
42          assertConditions(TYPE_AND + FALSE + FALSE + TYPE_CLOSE, false);//false AND false = false
43      }
44  
45      public void testOr() throws DocumentException, PluginParseException
46      {
47          assertConditions(TYPE_OR + TRUE + TRUE + TYPE_CLOSE, true);//true OR true = true
48          assertConditions(TYPE_OR + TRUE + FALSE + TYPE_CLOSE, true);//true OR false = true
49          assertConditions(TYPE_OR + FALSE + TRUE + TYPE_CLOSE, true);//false OR true = true
50          assertConditions(TYPE_OR + FALSE + FALSE + TYPE_CLOSE, false);//false OR false = false
51      }
52  
53      //test nested AND's - normally all nested AND's should be a single AND
54      public void testNestedAnd() throws DocumentException, PluginParseException
55      {
56          //nested AND'ed conditions
57          assertConditions(TYPE_AND +
58                              TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
59                              TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
60                           TYPE_CLOSE, true);//(true AND true) AND (true AND true) = true
61  
62          //same as above but without explicit AND
63          assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
64                           TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);//(true AND true) AND (true AND true) = true
65  
66          assertConditions(TYPE_AND +
67                              TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
68                              TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
69                           TYPE_CLOSE, false);//(true AND true) AND (false AND true) = false
70      }
71  
72      //test nested OR's - normally all nested OR's should be a single OR
73      public void testNestedOr() throws DocumentException, PluginParseException
74      {
75          //nested OR'ed conditions
76          assertConditions(TYPE_OR +
77                              TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
78                              TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
79                           TYPE_CLOSE, true);//(false OR false) OR (false OR true) = true
80  
81          assertConditions(TYPE_OR +
82                              TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
83                              TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
84                           TYPE_CLOSE, false);//(false OR false) OR (false OR false) = false
85      }
86  
87      public void testNestedMix() throws DocumentException, PluginParseException
88      {
89          //AND with nested OR conditions
90          assertConditions(TYPE_AND +
91                              TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
92                              TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
93                           TYPE_CLOSE, false);//(false OR false) AND (false OR true) = false
94  
95          assertConditions(TYPE_AND +
96                              TYPE_OR + TRUE + FALSE + TYPE_CLOSE +
97                              TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
98                           TYPE_CLOSE, true);//(true OR false) AND (false OR true) = true
99  
100         //OR with nested AND conditions
101         assertConditions(TYPE_OR +
102                             TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
103                             TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
104                          TYPE_CLOSE, false);//(false AND false) OR (false AND true) = false
105 
106         assertConditions(TYPE_OR +
107                             TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
108                             TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
109                          TYPE_CLOSE, true);//(false AND false) OR (true AND true) = true
110     }
111 
112     public void testComplex() throws DocumentException, PluginParseException
113     {
114         assertConditions(TRUE +
115                          TYPE_OR +
116                             TYPE_AND +
117                                 FALSE + FALSE +
118                             TYPE_CLOSE +
119                             FALSE +
120                             TYPE_AND +
121                                 TRUE +
122                                 TYPE_OR +
123                                     FALSE + TRUE +
124                                 TYPE_CLOSE +
125                             TYPE_CLOSE +
126                          TYPE_CLOSE, true);//true AND ((false AND false) OR false OR (true AND (false OR true))) = true
127     }
128 
129     public void assertConditions(String conditionElement, boolean expectedResult) throws DocumentException, PluginParseException
130     {
131         String rootElement = "<root>" + conditionElement + "</root>";
132         Document document = DocumentHelper.parseText(rootElement);
133 
134         Condition condition = descriptor.makeConditions(document.getRootElement(), AbstractWebFragmentModuleDescriptor.COMPOSITE_TYPE_AND);
135 
136         assertEquals(expectedResult, condition.shouldDisplay(null));
137     }
138 }