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