1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.refactoring.job

File XClassDeletingListenerTest.java

 

Code metrics

0
135
4
1
313
222
4
0.03
33.75
4
1

Classes

Class Line # Actions
XClassDeletingListenerTest 83 135 0% 4 0
1.0100%
 

Contributing tests

This file is covered by 4 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.refactoring.job;
21   
22    import java.util.Arrays;
23    import java.util.Collection;
24    import java.util.Collections;
25    import java.util.HashMap;
26    import java.util.HashSet;
27    import java.util.Map;
28    import java.util.Set;
29    import java.util.concurrent.TimeUnit;
30   
31    import org.junit.jupiter.api.extension.RegisterExtension;
32   
33    import javax.inject.Named;
34   
35    import org.junit.jupiter.api.Test;
36    import org.xwiki.bridge.DocumentAccessBridge;
37    import org.xwiki.bridge.event.DocumentsDeletingEvent;
38    import org.xwiki.job.Job;
39    import org.xwiki.job.Request;
40    import org.xwiki.job.event.status.JobStatus;
41    import org.xwiki.model.EntityType;
42    import org.xwiki.model.internal.reference.DefaultSymbolScheme;
43    import org.xwiki.model.internal.reference.LocalStringEntityReferenceSerializer;
44    import org.xwiki.model.reference.DocumentReference;
45    import org.xwiki.model.reference.EntityReference;
46    import org.xwiki.model.reference.EntityReferenceResolver;
47    import org.xwiki.query.Query;
48    import org.xwiki.query.QueryManager;
49    import org.xwiki.refactoring.job.question.EntitySelection;
50    import org.xwiki.test.LogLevel;
51    import org.xwiki.test.annotation.ComponentList;
52    import org.xwiki.test.junit5.LogCaptureExtension;
53    import org.xwiki.test.junit5.mockito.ComponentTest;
54    import org.xwiki.test.junit5.mockito.InjectMockComponents;
55    import org.xwiki.test.junit5.mockito.MockComponent;
56   
57    import static org.junit.Assert.assertEquals;
58    import static org.junit.Assert.assertFalse;
59    import static org.junit.Assert.assertTrue;
60    import static org.mockito.ArgumentMatchers.any;
61    import static org.mockito.ArgumentMatchers.anyInt;
62    import static org.mockito.ArgumentMatchers.anyLong;
63    import static org.mockito.ArgumentMatchers.eq;
64    import static org.mockito.Mockito.doAnswer;
65    import static org.mockito.Mockito.doThrow;
66    import static org.mockito.Mockito.mock;
67    import static org.mockito.Mockito.times;
68    import static org.mockito.Mockito.verify;
69    import static org.mockito.Mockito.verifyZeroInteractions;
70    import static org.mockito.Mockito.when;
71   
72    /**
73    * Validate the behaviour of {@link XClassDeletingListener}
74    *
75    * @version $Id: 79ec52ff28e943534b849801a912b645a0630b68 $
76    * @since 10.10RC1
77    */
78    @ComponentTest
79    @ComponentList({
80    LocalStringEntityReferenceSerializer.class,
81    DefaultSymbolScheme.class
82    })
 
83    public class XClassDeletingListenerTest
84    {
85    @MockComponent
86    private EntityReferenceResolver<String> resolver;
87   
88    @MockComponent
89    private QueryManager queryManager;
90   
91    @MockComponent
92    private DocumentAccessBridge documentAccessBridge;
93   
94    @RegisterExtension
95    LogCaptureExtension logCapture = new LogCaptureExtension(LogLevel.WARN);
96   
97    @InjectMockComponents
98    private XClassDeletingListener deletingListener;
99   
 
100  1 toggle @Test
101    public void test() throws Exception
102    {
103  1 Request request = mock(Request.class);
104  1 Job job = mock(Job.class);
105  1 JobStatus status = mock(JobStatus.class);
106  1 when(job.getRequest()).thenReturn(request);
107  1 when(request.isInteractive()).thenReturn(true);
108  1 when(job.getStatus()).thenReturn(status);
109   
110  1 Map<EntityReference, EntitySelection> concernedEntities = new HashMap<>();
111   
112  1 DocumentReference xclass1 = new DocumentReference("wiki1", "a", "xclass1");
113  1 DocumentReference simplePage1 = new DocumentReference("wiki1", "b", "simplepage");
114  1 DocumentReference simplePage2 = new DocumentReference("wiki2", "a", "otherpage");
115  1 DocumentReference xclass2 = new DocumentReference("wiki2", "b", "xclass2");
116   
117  1 EntitySelection xclass1Selection = new EntitySelection(xclass1);
118  1 EntitySelection simplePage1Selection = new EntitySelection(simplePage1);
119  1 EntitySelection simplePage2Selection = new EntitySelection(simplePage2);
120  1 EntitySelection xclass2Selection = new EntitySelection(xclass2);
121   
122  1 concernedEntities.put(xclass1, xclass1Selection);
123  1 concernedEntities.put(simplePage1, simplePage1Selection);
124  1 concernedEntities.put(simplePage2, simplePage2Selection);
125  1 concernedEntities.put(xclass2, xclass2Selection);
126   
127  1 DocumentReference docObjReference1 = new DocumentReference("wiki1", "a", "xobject1");
128  1 DocumentReference docObjReference2 = new DocumentReference("wiki1", "b", "xobject2");
129  1 DocumentReference docObjReference3 = new DocumentReference("wiki2", "b", "xobject3");
130   
131  1 Query query = mock(Query.class);
132  1 when(queryManager.createQuery(any(), eq(Query.HQL))).thenReturn(query);
133  1 when(query.setLimit(anyInt())).thenReturn(query);
134   
135  1 Query query1 = mock(Query.class);
136  1 when(query.bindValue("className", "a.xclass1")).thenReturn(query1);
137  1 when(query1.setWiki("wiki1")).thenReturn(query1);
138  1 when(query1.execute())
139    .thenReturn(Arrays.asList("a.xobject1", "b.xobject2"));
140   
141  1 Query query2 = mock(Query.class);
142  1 when(query.bindValue("className", "b.simplepage")).thenReturn(query2);
143  1 when(query2.setWiki("wiki1")).thenReturn(query2);
144  1 when(query2.execute()).thenReturn(Collections.emptyList());
145   
146  1 Query query3 = mock(Query.class);
147  1 when(query.bindValue("className", "a.otherpage")).thenReturn(query3);
148  1 when(query3.setWiki("wiki2")).thenReturn(query3);
149  1 when(query3.execute()).thenReturn(Collections.emptyList());
150   
151  1 Query query4 = mock(Query.class);
152  1 when(query.bindValue("className", "b.xclass2")).thenReturn(query4);
153  1 when(query4.setWiki("wiki2")).thenReturn(query4);
154  1 when(query4.execute()).thenReturn(Arrays.asList("b.xobject3"));
155   
156  1 when(resolver.resolve("a.xobject1", EntityType.DOCUMENT, xclass1)).thenReturn(docObjReference1);
157  1 when(resolver.resolve("b.xobject2", EntityType.DOCUMENT, xclass1)).thenReturn(docObjReference2);
158  1 when(resolver.resolve("b.xobject3", EntityType.DOCUMENT, xclass2)).thenReturn(docObjReference3);
159   
160  1 when(documentAccessBridge.isAdvancedUser(any())).thenReturn(true);
161   
162  1 doAnswer(invocationOnMock -> {
163  1 XClassBreakingQuestion question = invocationOnMock.getArgument(0);
164  1 assertEquals(concernedEntities, question.getConcernedEntities());
165   
166  1 Set<EntitySelection> expectedFreePages = new HashSet<>();
167  1 expectedFreePages.add(simplePage1Selection);
168  1 expectedFreePages.add(simplePage2Selection);
169   
170  1 assertEquals(expectedFreePages, question.getFreePages());
171   
172  1 Set<EntitySelection> expectedXPages = new HashSet<>();
173  1 expectedXPages.add(xclass1Selection);
174  1 expectedXPages.add(xclass2Selection);
175   
176  1 assertEquals(expectedXPages, question.getXClassPages());
177   
178  1 Map<EntityReference, Set<EntityReference>> expectedImpactedObjects = new HashMap<>();
179   
180  1 Set<EntityReference> expectedSetClass1 = new HashSet<>();
181  1 expectedSetClass1.add(docObjReference1);
182  1 expectedSetClass1.add(docObjReference2);
183  1 expectedImpactedObjects.put(xclass1, expectedSetClass1);
184   
185  1 Set<EntityReference> expectedSetClass2 = new HashSet<>();
186  1 expectedSetClass2.add(docObjReference3);
187  1 expectedImpactedObjects.put(xclass2, expectedSetClass2);
188   
189  1 assertEquals(expectedImpactedObjects, question.getImpactedObjects());
190   
191    // Assert nothing is select by default
192  1 for (EntitySelection selection : question.getConcernedEntities().values()) {
193  4 assertFalse(selection.getEntityReference() + " should not be selected", selection.isSelected());
194    }
195  1 return null;
196    }).when(status).ask(any(), anyLong(), any());
197   
198    // Test
199  1 DocumentsDeletingEvent event = new DocumentsDeletingEvent();
200  1 this.deletingListener.onEvent(event, job, concernedEntities);
201   
202    // Check
203  1 verify(status, times(1)).ask(any(), eq(5L), eq(TimeUnit.MINUTES));
204  1 this.logCapture.ignoreAllMessages();
205    }
206   
 
207  1 toggle @Test
208    public void testWhenNonInteractive() throws Exception
209    {
210  1 Request request = mock(Request.class);
211  1 Job job = mock(Job.class);
212  1 when(job.getRequest()).thenReturn(request);
213  1 when(request.isInteractive()).thenReturn(false);
214  1 JobStatus status = mock(JobStatus.class);
215  1 when(job.getStatus()).thenReturn(status);
216   
217    // Test
218  1 DocumentsDeletingEvent event = new DocumentsDeletingEvent();
219  1 this.deletingListener.onEvent(event, job, null);
220   
221    // Verify
222  1 assertEquals("XClass deleting listener will not check the document in non-interactive mode.",
223    logCapture.getMessage(0));
224  1 verifyZeroInteractions(status);
225    }
226   
 
227  1 toggle @Test
228    public void testCancel() throws Exception
229    {
230  1 Request request = mock(Request.class);
231  1 Job job = mock(Job.class);
232  1 JobStatus status = mock(JobStatus.class);
233  1 when(job.getRequest()).thenReturn(request);
234  1 when(request.isInteractive()).thenReturn(true);
235  1 when(job.getStatus()).thenReturn(status);
236   
237  1 Map<EntityReference, EntitySelection> concernedEntities = new HashMap<>();
238  1 DocumentReference doc1 = new DocumentReference("a", "b", "c1");
239  1 concernedEntities.put(doc1, new EntitySelection(doc1));
240   
241  1 Query query = mock(Query.class);
242  1 when(queryManager.createQuery(any(),any())).thenReturn(query);
243  1 when(query.setLimit(anyInt())).thenReturn(query);
244  1 when(query.bindValue(any(), any())).thenReturn(query);
245  1 when(query.setWiki(any())).thenReturn(query);
246  1 when(query.execute()).thenReturn(Arrays.asList("space.document"));
247   
248  1 when(resolver.resolve("space.document", EntityType.DOCUMENT))
249    .thenReturn(new DocumentReference("wiki", "space", "document"));
250   
251  1 InterruptedException e = new InterruptedException();
252  1 doThrow(e).when(status).ask(any(), anyLong(), any());
253   
254  1 when(this.documentAccessBridge.isAdvancedUser(any())).thenReturn(true);
255   
256    // Test
257  1 DocumentsDeletingEvent event = mock(DocumentsDeletingEvent.class);
258  1 this.deletingListener.onEvent(event, job, concernedEntities);
259   
260    // Check
261  1 verify(status, times(1)).ask(any(), eq(5L), eq(TimeUnit.MINUTES));
262  1 verify(event).cancel(eq("Question has been interrupted."));
263  1 assertEquals("Confirm question has been interrupted.", this.logCapture.getMessage(0));
264    }
265   
 
266  1 toggle @Test
267    public void testSimpleUser() throws Exception
268    {
269  1 Request request = mock(Request.class);
270  1 Job job = mock(Job.class);
271  1 JobStatus status = mock(JobStatus.class);
272  1 when(job.getRequest()).thenReturn(request);
273  1 when(request.isInteractive()).thenReturn(true);
274  1 when(job.getStatus()).thenReturn(status);
275   
276  1 Map<EntityReference, EntitySelection> concernedEntities = new HashMap<>();
277  1 DocumentReference doc1 = new DocumentReference("a", "b", "c1");
278  1 concernedEntities.put(doc1, new EntitySelection(doc1));
279   
280  1 Query query = mock(Query.class);
281  1 when(queryManager.createQuery(any(),any())).thenReturn(query);
282  1 when(query.setLimit(anyInt())).thenReturn(query);
283  1 when(query.bindValue(any(), any())).thenReturn(query);
284  1 when(query.setWiki(any())).thenReturn(query);
285  1 when(query.execute()).thenReturn(Arrays.asList("space.document"));
286   
287  1 when(resolver.resolve("space.document", EntityType.DOCUMENT))
288    .thenReturn(new DocumentReference("wiki", "space", "document"));
289   
290  1 when(this.documentAccessBridge.isAdvancedUser(any())).thenReturn(false);
291   
292  1 doAnswer(invocationOnMock -> {
293  1 XClassBreakingQuestion question = invocationOnMock.getArgument(0);
294  1 assertEquals(concernedEntities, question.getConcernedEntities());
295   
296  1 assertTrue(question.getFreePages().isEmpty());
297  1 assertEquals(1, question.getXClassPages().size());
298  1 assertEquals(1, question.getImpactedObjects().size());
299  1 assertTrue(question.isRefactoringForbidden());
300  1 return null;
301    }).when(status).ask(any(), anyLong(), any());
302   
303   
304    // Test
305  1 DocumentsDeletingEvent event = mock(DocumentsDeletingEvent.class);
306  1 this.deletingListener.onEvent(event, job, concernedEntities);
307   
308    // Check
309  1 verify(status, times(1)).ask(any(), eq(1L), eq(TimeUnit.MINUTES));
310  1 verify(event).cancel(eq("The question has been canceled because this refactoring is forbidden."));
311    }
312   
313    }