1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package com.xpn.xwiki.store.hibernate.query; |
21 |
|
|
22 |
|
import java.util.Arrays; |
23 |
|
import java.util.Collections; |
24 |
|
import java.util.Date; |
25 |
|
import java.util.HashMap; |
26 |
|
import java.util.List; |
27 |
|
import java.util.Map; |
28 |
|
|
29 |
|
import org.hibernate.SQLQuery; |
30 |
|
import org.hibernate.Session; |
31 |
|
import org.hibernate.cfg.Configuration; |
32 |
|
import org.hibernate.engine.NamedSQLQueryDefinition; |
33 |
|
import org.junit.Before; |
34 |
|
import org.junit.Rule; |
35 |
|
import org.junit.Test; |
36 |
|
import org.mockito.invocation.InvocationOnMock; |
37 |
|
import org.mockito.stubbing.Answer; |
38 |
|
import org.xwiki.context.Execution; |
39 |
|
import org.xwiki.context.ExecutionContext; |
40 |
|
import org.xwiki.query.Query; |
41 |
|
import org.xwiki.query.QueryException; |
42 |
|
import org.xwiki.query.QueryFilter; |
43 |
|
import org.xwiki.query.internal.DefaultQuery; |
44 |
|
import org.xwiki.security.authorization.ContextualAuthorizationManager; |
45 |
|
import org.xwiki.security.authorization.Right; |
46 |
|
import org.xwiki.test.mockito.MockitoComponentMockingRule; |
47 |
|
|
48 |
|
import com.xpn.xwiki.XWikiContext; |
49 |
|
import com.xpn.xwiki.XWikiException; |
50 |
|
import com.xpn.xwiki.store.XWikiHibernateBaseStore; |
51 |
|
import com.xpn.xwiki.store.XWikiHibernateStore; |
52 |
|
import com.xpn.xwiki.store.hibernate.HibernateSessionFactory; |
53 |
|
|
54 |
|
import static org.junit.Assert.assertEquals; |
55 |
|
import static org.junit.Assert.assertSame; |
56 |
|
import static org.junit.Assert.fail; |
57 |
|
import static org.mockito.ArgumentMatchers.any; |
58 |
|
import static org.mockito.Mockito.mock; |
59 |
|
import static org.mockito.Mockito.verify; |
60 |
|
import static org.mockito.Mockito.when; |
61 |
|
|
62 |
|
|
63 |
|
@link |
64 |
|
|
65 |
|
@version |
66 |
|
|
|
|
| 95.8% |
Uncovered Elements: 6 (142) |
Complexity: 34 |
Complexity Density: 0.31 |
|
67 |
|
public class HqlQueryExecutorTest |
68 |
|
{ |
69 |
|
@Rule |
70 |
|
public MockitoComponentMockingRule<HqlQueryExecutor> mocker = new MockitoComponentMockingRule<>( |
71 |
|
HqlQueryExecutor.class); |
72 |
|
|
73 |
|
private ContextualAuthorizationManager authorization; |
74 |
|
|
75 |
|
private boolean hasProgrammingRight; |
76 |
|
|
77 |
|
|
78 |
|
|
79 |
|
|
80 |
|
private HqlQueryExecutor executor; |
81 |
|
|
82 |
|
private XWikiHibernateStore store; |
83 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 1 |
Complexity Density: 0.06 |
|
84 |
22 |
@Before... |
85 |
|
public void before() throws Exception |
86 |
|
{ |
87 |
22 |
HibernateSessionFactory sessionFactory = this.mocker.getInstance(HibernateSessionFactory.class); |
88 |
22 |
when(sessionFactory.getConfiguration()).thenReturn(new Configuration()); |
89 |
|
|
90 |
22 |
this.executor = this.mocker.getComponentUnderTest(); |
91 |
22 |
this.authorization = this.mocker.getInstance(ContextualAuthorizationManager.class); |
92 |
|
|
93 |
22 |
when(this.authorization.hasAccess(Right.PROGRAM)).then(new Answer<Boolean>() |
94 |
|
{ |
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
95 |
10 |
@Override... |
96 |
|
public Boolean answer(InvocationOnMock invocation) throws Throwable |
97 |
|
{ |
98 |
10 |
return hasProgrammingRight; |
99 |
|
} |
100 |
|
}); |
101 |
|
|
102 |
22 |
this.hasProgrammingRight = true; |
103 |
|
|
104 |
|
|
105 |
|
|
106 |
22 |
Execution execution = this.mocker.getInstance(Execution.class); |
107 |
22 |
ExecutionContext executionContext = mock(ExecutionContext.class); |
108 |
22 |
when(execution.getContext()).thenReturn(executionContext); |
109 |
22 |
XWikiContext xwikiContext = mock(XWikiContext.class); |
110 |
22 |
when(executionContext.getProperty(XWikiContext.EXECUTIONCONTEXT_KEY)).thenReturn(xwikiContext); |
111 |
22 |
when(xwikiContext.getWikiId()).thenReturn("currentwikid"); |
112 |
|
|
113 |
22 |
com.xpn.xwiki.XWiki xwiki = mock(com.xpn.xwiki.XWiki.class); |
114 |
22 |
when(xwikiContext.getWiki()).thenReturn(xwiki); |
115 |
22 |
this.store = mock(XWikiHibernateStore.class); |
116 |
22 |
when(xwiki.getHibernateStore()).thenReturn(store); |
117 |
|
} |
118 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (9) |
Complexity: 3 |
Complexity Density: 0.6 |
|
119 |
9 |
private void execute(String statement, Boolean withProgrammingRights) throws QueryException... |
120 |
|
{ |
121 |
9 |
this.hasProgrammingRight = withProgrammingRights != null ? withProgrammingRights : true; |
122 |
|
|
123 |
9 |
DefaultQuery query = new DefaultQuery(statement, Query.HQL, this.executor); |
124 |
9 |
if (withProgrammingRights != null) { |
125 |
8 |
query.checkCurrentAuthor(true); |
126 |
|
} |
127 |
|
|
128 |
9 |
this.executor.execute(query); |
129 |
|
} |
130 |
|
|
|
|
| 85.7% |
Uncovered Elements: 1 (7) |
Complexity: 2 |
Complexity Density: 0.4 |
|
131 |
2 |
private void executeNamed(String name, Boolean withProgrammingRights) throws QueryException... |
132 |
|
{ |
133 |
2 |
this.hasProgrammingRight = withProgrammingRights; |
134 |
|
|
135 |
2 |
DefaultQuery query = new DefaultQuery(name, this.executor); |
136 |
2 |
if (withProgrammingRights != null) { |
137 |
2 |
query.checkCurrentAuthor(true); |
138 |
|
} |
139 |
|
|
140 |
2 |
this.executor.execute(query); |
141 |
|
} |
142 |
|
|
143 |
|
|
144 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
145 |
1 |
@Test... |
146 |
|
public void completeShortStatementWhenEmpty() |
147 |
|
{ |
148 |
1 |
assertEquals("select doc.fullName from XWikiDocument doc ", this.executor.completeShortFormStatement("")); |
149 |
|
} |
150 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
151 |
1 |
@Test... |
152 |
|
public void completeShortStatementStartingWithWhere() |
153 |
|
{ |
154 |
1 |
assertEquals("select doc.fullName from XWikiDocument doc where doc.author='XWiki.Admin'", |
155 |
|
this.executor.completeShortFormStatement("where doc.author='XWiki.Admin'")); |
156 |
|
} |
157 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
158 |
1 |
@Test... |
159 |
|
public void completeShortStatementStartingWithFrom() |
160 |
|
{ |
161 |
1 |
assertEquals("select doc.fullName from XWikiDocument doc , BaseObject obj where doc.fullName=obj.name " |
162 |
|
+ "and obj.className='XWiki.MyClass'", this.executor.completeShortFormStatement(", BaseObject obj where " |
163 |
|
+ "doc.fullName=obj.name and obj.className='XWiki.MyClass'")); |
164 |
|
} |
165 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
166 |
1 |
@Test... |
167 |
|
public void completeShortStatementStartingWithOrderBy() |
168 |
|
{ |
169 |
1 |
assertEquals("select doc.fullName from XWikiDocument doc order by doc.date desc", |
170 |
|
this.executor.completeShortFormStatement("order by doc.date desc")); |
171 |
|
} |
172 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
173 |
1 |
@Test... |
174 |
|
public void completeShortStatementPassingAnAlreadyCompleteQuery() |
175 |
|
{ |
176 |
1 |
assertEquals("select doc.fullName from XWikiDocument doc order by doc.date desc", |
177 |
|
this.executor |
178 |
|
.completeShortFormStatement("select doc.fullName from XWikiDocument doc order by doc.date desc")); |
179 |
|
} |
180 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
181 |
1 |
@Test... |
182 |
|
public void completeShortStatementPassingAQueryOnSomethingElseThanADocument() |
183 |
|
{ |
184 |
1 |
assertEquals("select lock.docId from XWikiLock as lock ", |
185 |
|
this.executor.completeShortFormStatement("select lock.docId from XWikiLock as lock ")); |
186 |
|
} |
187 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
188 |
1 |
@Test... |
189 |
|
public void setNamedParameter() |
190 |
|
{ |
191 |
1 |
org.hibernate.Query query = mock(org.hibernate.Query.class); |
192 |
1 |
String name = "abc"; |
193 |
1 |
Date value = new Date(); |
194 |
1 |
this.executor.setNamedParameter(query, name, value); |
195 |
|
|
196 |
1 |
verify(query).setParameter(name, value); |
197 |
|
} |
198 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
199 |
1 |
@Test... |
200 |
|
public void setNamedParameterList() |
201 |
|
{ |
202 |
1 |
org.hibernate.Query query = mock(org.hibernate.Query.class); |
203 |
1 |
String name = "foo"; |
204 |
1 |
List<String> value = Arrays.asList("one", "two", "three"); |
205 |
1 |
this.executor.setNamedParameter(query, name, value); |
206 |
|
|
207 |
1 |
verify(query).setParameterList(name, value); |
208 |
|
} |
209 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0.2 |
1PASS
|
|
210 |
1 |
@Test... |
211 |
|
public void setNamedParameterArray() |
212 |
|
{ |
213 |
1 |
org.hibernate.Query query = mock(org.hibernate.Query.class); |
214 |
1 |
String name = "bar"; |
215 |
1 |
Integer[] value = new Integer[] { 1, 2, 3 }; |
216 |
1 |
this.executor.setNamedParameter(query, name, value); |
217 |
|
|
218 |
1 |
verify(query).setParameterList(name, value); |
219 |
|
} |
220 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 1 |
Complexity Density: 0.06 |
1PASS
|
|
221 |
1 |
@Test... |
222 |
|
public void populateParameters() |
223 |
|
{ |
224 |
1 |
org.hibernate.Query hquery = mock(org.hibernate.Query.class); |
225 |
1 |
Query query = mock(Query.class); |
226 |
|
|
227 |
1 |
int offset = 13; |
228 |
1 |
when(query.getOffset()).thenReturn(offset); |
229 |
|
|
230 |
1 |
int limit = 7; |
231 |
1 |
when(query.getLimit()).thenReturn(limit); |
232 |
|
|
233 |
1 |
Map<String, Object> namedParameters = new HashMap<String, Object>(); |
234 |
1 |
namedParameters.put("alice", 10); |
235 |
1 |
List<String> listValue = Collections.singletonList("yellow"); |
236 |
1 |
namedParameters.put("bob", listValue); |
237 |
1 |
when(query.getNamedParameters()).thenReturn(namedParameters); |
238 |
|
|
239 |
1 |
this.executor.populateParameters(hquery, query); |
240 |
|
|
241 |
1 |
verify(hquery).setFirstResult(offset); |
242 |
1 |
verify(hquery).setMaxResults(limit); |
243 |
1 |
verify(hquery).setParameter("alice", 10); |
244 |
1 |
verify(hquery).setParameterList("bob", listValue); |
245 |
|
} |
246 |
|
|
|
|
| 87.5% |
Uncovered Elements: 1 (8) |
Complexity: 2 |
Complexity Density: 0.25 |
1PASS
|
|
247 |
1 |
@Test... |
248 |
|
public void executeWhenStoreException() throws Exception |
249 |
|
{ |
250 |
1 |
XWikiException exception = mock(XWikiException.class); |
251 |
1 |
when(exception.getMessage()).thenReturn("nestedmessage"); |
252 |
|
|
253 |
1 |
when(this.store.executeRead(any(XWikiContext.class), any(XWikiHibernateBaseStore.HibernateCallback.class))) |
254 |
|
.thenThrow(exception); |
255 |
|
|
256 |
1 |
try { |
257 |
1 |
execute("statement", null); |
258 |
0 |
fail("Should have thrown an exception here"); |
259 |
|
} catch (QueryException expected) { |
260 |
1 |
assertEquals("Exception while executing query. Query statement = [statement]", expected.getMessage()); |
261 |
|
|
262 |
1 |
assertEquals("nestedmessage", expected.getCause().getMessage()); |
263 |
|
} |
264 |
|
} |
265 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 1 |
Complexity Density: 0.06 |
1PASS
|
|
266 |
1 |
@Test... |
267 |
|
@SuppressWarnings("unchecked") |
268 |
|
public void createNamedNativeHibernateQuery() throws Exception |
269 |
|
{ |
270 |
1 |
DefaultQuery query = new DefaultQuery("queryName", this.executor); |
271 |
1 |
QueryFilter filter = mock(QueryFilter.class); |
272 |
1 |
query.addFilter(filter); |
273 |
|
|
274 |
1 |
Session session = mock(Session.class); |
275 |
1 |
SQLQuery sqlQuery = mock(SQLQuery.class); |
276 |
1 |
when(session.getNamedQuery(query.getStatement())).thenReturn(sqlQuery); |
277 |
|
|
278 |
1 |
when(sqlQuery.getQueryString()).thenReturn("foo"); |
279 |
1 |
when(filter.filterStatement("foo", "sql")).thenReturn("bar"); |
280 |
|
|
281 |
1 |
SQLQuery finalQuery = mock(SQLQuery.class); |
282 |
1 |
when(session.createSQLQuery("bar")).thenReturn(finalQuery); |
283 |
|
|
284 |
1 |
NamedSQLQueryDefinition definition = mock(NamedSQLQueryDefinition.class); |
285 |
1 |
when(definition.getResultSetRef()).thenReturn("someResultSet"); |
286 |
|
|
287 |
1 |
HibernateSessionFactory sessionFactory = this.mocker.getInstance(HibernateSessionFactory.class); |
288 |
1 |
sessionFactory.getConfiguration().getNamedSQLQueries().put(query.getStatement(), definition); |
289 |
|
|
290 |
1 |
assertSame(finalQuery, this.executor.createHibernateQuery(session, query)); |
291 |
|
|
292 |
1 |
verify(finalQuery).setResultSetMapping(definition.getResultSetRef()); |
293 |
|
} |
294 |
|
|
295 |
|
|
296 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
297 |
1 |
@Test... |
298 |
|
public void executeShortWhereHQLQueryWithProgrammingRights() throws QueryException |
299 |
|
{ |
300 |
1 |
execute("where doc.space='Main'", true); |
301 |
|
} |
302 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
303 |
1 |
@Test... |
304 |
|
public void executeShortFromHQLQueryWithProgrammingRights() throws QueryException |
305 |
|
{ |
306 |
1 |
execute(", BaseObject as obj", true); |
307 |
|
} |
308 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
309 |
1 |
@Test... |
310 |
|
public void executeCompleteHQLQueryWithProgrammingRights() throws QueryException |
311 |
|
{ |
312 |
1 |
execute("select u from XWikiDocument as doc", true); |
313 |
|
|
314 |
|
} |
315 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
316 |
1 |
@Test... |
317 |
|
public void executeNamedQueryWithProgrammingRights() throws QueryException |
318 |
|
{ |
319 |
1 |
executeNamed("somename", true); |
320 |
|
} |
321 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
322 |
1 |
@Test... |
323 |
|
public void executeShortWhereHQLQueryWithoutProgrammingRights() throws QueryException |
324 |
|
{ |
325 |
1 |
execute("where doc.space='Main'", false); |
326 |
|
} |
327 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
1PASS
|
|
328 |
1 |
@Test... |
329 |
|
public void executeShortFromHQLQueryWithoutProgrammingRights() throws QueryException |
330 |
|
{ |
331 |
1 |
execute(", BaseObject as obj", false); |
332 |
|
} |
333 |
|
|
334 |
|
|
335 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
1PASS
|
|
336 |
1 |
@Test... |
337 |
|
public void executeWhenNotAllowedSelect() throws Exception |
338 |
|
{ |
339 |
1 |
try { |
340 |
1 |
execute("select notallowed.name from NotAllowedTable notallowed", false); |
341 |
0 |
fail("Should have thrown an exception here"); |
342 |
|
} catch (QueryException expected) { |
343 |
1 |
assertEquals("The query requires programming right." |
344 |
|
+ " Query statement = [select notallowed.name from NotAllowedTable notallowed]", expected.getMessage()); |
345 |
|
} |
346 |
|
} |
347 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
1PASS
|
|
348 |
1 |
@Test... |
349 |
|
public void executeDeleteWithoutProgrammingRight() throws Exception |
350 |
|
{ |
351 |
1 |
try { |
352 |
1 |
execute("delete from XWikiDocument as doc", false); |
353 |
0 |
fail("Should have thrown an exception here"); |
354 |
|
} catch (QueryException expected) { |
355 |
1 |
assertEquals("The query requires programming right. Query statement = [delete from XWikiDocument as doc]", |
356 |
|
expected.getMessage()); |
357 |
|
} |
358 |
|
} |
359 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
1PASS
|
|
360 |
1 |
@Test... |
361 |
|
public void executeNamedQueryWithoutProgrammingRight() throws Exception |
362 |
|
{ |
363 |
1 |
try { |
364 |
1 |
executeNamed("somename", false); |
365 |
0 |
fail("Should have thrown an exception here"); |
366 |
|
} catch (QueryException expected) { |
367 |
1 |
assertEquals("Named queries requires programming right. Named query = [somename]", expected.getMessage()); |
368 |
|
} |
369 |
|
} |
370 |
|
|
|
|
| 75% |
Uncovered Elements: 1 (4) |
Complexity: 2 |
Complexity Density: 0.5 |
1PASS
|
|
371 |
1 |
@Test... |
372 |
|
public void executeUpdateWithoutProgrammingRight() throws Exception |
373 |
|
{ |
374 |
1 |
try { |
375 |
1 |
execute("update XWikiDocument set name='name'", false); |
376 |
0 |
fail("Should have thrown an exception here"); |
377 |
|
} catch (QueryException expected) { |
378 |
1 |
assertEquals( |
379 |
|
"The query requires programming right. Query statement = [update XWikiDocument set name='name']", |
380 |
|
expected.getMessage()); |
381 |
|
} |
382 |
|
} |
383 |
|
} |