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);
43 assertConditions(FALSE, false);
44 assertConditions(NOT_TRUE, false);
45 assertConditions(NOT_FALSE, true);
46 }
47
48 @Test
49 public void testAnd() throws DocumentException, PluginParseException
50 {
51
52 assertConditions(TRUE + TRUE, true);
53 assertConditions(TRUE + FALSE, false);
54 assertConditions(FALSE + TRUE, false);
55 assertConditions(FALSE + FALSE, false);
56
57
58 assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);
59 assertConditions(TYPE_AND + TRUE + FALSE + TYPE_CLOSE, false);
60 assertConditions(TYPE_AND + FALSE + TRUE + TYPE_CLOSE, false);
61 assertConditions(TYPE_AND + FALSE + FALSE + TYPE_CLOSE, false);
62 }
63
64 @Test
65 public void testOr() throws DocumentException, PluginParseException
66 {
67 assertConditions(TYPE_OR + TRUE + TRUE + TYPE_CLOSE, true);
68 assertConditions(TYPE_OR + TRUE + FALSE + TYPE_CLOSE, true);
69 assertConditions(TYPE_OR + FALSE + TRUE + TYPE_CLOSE, true);
70 assertConditions(TYPE_OR + FALSE + FALSE + TYPE_CLOSE, false);
71 }
72
73
74 @Test
75 public void testNestedAnd() throws DocumentException, PluginParseException
76 {
77
78 assertConditions(TYPE_AND +
79 TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
80 TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
81 TYPE_CLOSE, true);
82
83
84 assertConditions(TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
85 TYPE_AND + TRUE + TRUE + TYPE_CLOSE, true);
86
87 assertConditions(TYPE_AND +
88 TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
89 TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
90 TYPE_CLOSE, false);
91 }
92
93
94 @Test
95 public void testNestedOr() throws DocumentException, PluginParseException
96 {
97
98 assertConditions(TYPE_OR +
99 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
100 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
101 TYPE_CLOSE, true);
102
103 assertConditions(TYPE_OR +
104 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
105 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
106 TYPE_CLOSE, false);
107 }
108
109 @Test
110 public void testNestedMix() throws DocumentException, PluginParseException
111 {
112
113 assertConditions(TYPE_AND +
114 TYPE_OR + FALSE + FALSE + TYPE_CLOSE +
115 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
116 TYPE_CLOSE, false);
117
118 assertConditions(TYPE_AND +
119 TYPE_OR + TRUE + FALSE + TYPE_CLOSE +
120 TYPE_OR + FALSE + TRUE + TYPE_CLOSE +
121 TYPE_CLOSE, true);
122
123
124 assertConditions(TYPE_OR +
125 TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
126 TYPE_AND + FALSE + TRUE + TYPE_CLOSE +
127 TYPE_CLOSE, false);
128
129 assertConditions(TYPE_OR +
130 TYPE_AND + FALSE + FALSE + TYPE_CLOSE +
131 TYPE_AND + TRUE + TRUE + TYPE_CLOSE +
132 TYPE_CLOSE, 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);
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 }