Skip to content

Commit 4de7287

Browse files
committed
XWIKI-21257: Rollback is not triggering a UserUpdatingDocumentEvent
* Ensure that the rollback API properly calls the check method * Back the changes in a unit test that check events triggered in rollback
1 parent bda646c commit 4de7287

File tree

8 files changed

+488
-11
lines changed

8 files changed

+488
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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.test;
21+
22+
import javax.inject.Inject;
23+
import javax.inject.Named;
24+
import javax.inject.Singleton;
25+
26+
import org.apache.commons.lang3.StringUtils;
27+
import org.slf4j.Logger;
28+
import org.xwiki.component.annotation.Component;
29+
import org.xwiki.model.reference.DocumentReference;
30+
import org.xwiki.observation.AbstractEventListener;
31+
import org.xwiki.observation.event.Event;
32+
33+
import com.xpn.xwiki.doc.XWikiDocument;
34+
import com.xpn.xwiki.internal.event.UserUpdatingDocumentEvent;
35+
36+
/**
37+
* Listener dedicated to cancel a specific rolling back event triggered in VersionIT test.
38+
*
39+
* @version $Id$
40+
* @since 14.10.17
41+
* @since 15.5.3
42+
* @since 15.8RC1
43+
*/
44+
@Component
45+
@Singleton
46+
@Named(CustomUserUpdatedDocumentEventListener.NAME)
47+
public class CustomUserUpdatedDocumentEventListener extends AbstractEventListener
48+
{
49+
static final String NAME = "CustomUserUpdatedDocumentEventListener";
50+
51+
@Inject
52+
private Logger logger;
53+
54+
/**
55+
* Default constructor.
56+
*/
57+
public CustomUserUpdatedDocumentEventListener()
58+
{
59+
super(NAME, new UserUpdatingDocumentEvent());
60+
}
61+
62+
@Override
63+
public void onEvent(Event event, Object source, Object data)
64+
{
65+
UserUpdatingDocumentEvent userEvent = (UserUpdatingDocumentEvent) event;
66+
XWikiDocument sourceDoc = (XWikiDocument) source;
67+
DocumentReference expectedReference = new DocumentReference("xwiki", "XWiki", "XWikiPreferences");
68+
if (StringUtils.equals(userEvent.getUserReference().getName(), "DeleteVersionTestUserCancelEvent")
69+
&& sourceDoc.getDocumentReference().equals(expectedReference)) {
70+
logger.info("Cancelling user event on purpose");
71+
userEvent.cancel();
72+
}
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
org.xwiki.test.CustomUserUpdatedDocumentEventListener
12
org.xwiki.test.TestMacro

Diff for: xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-test/xwiki-platform-flamingo-skin-test-docker/src/test/it/org/xwiki/flamingo/test/docker/VersionIT.java

+324
Large diffs are not rendered by default.

Diff for: xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/XWiki.java

+53-7
Original file line numberDiff line numberDiff line change
@@ -4708,6 +4708,27 @@ public void checkDeletingDocument(DocumentReference userReference, XWikiDocument
47084708
*/
47094709
public void deleteDocumentVersions(XWikiDocument document, String version1, String version2, XWikiContext context)
47104710
throws XWikiException
4711+
{
4712+
deleteDocumentVersions(document, version1, version2, false, context);
4713+
}
4714+
4715+
/**
4716+
* Delete a range of versions from a document history.
4717+
*
4718+
* @param document the document from which to delete versions
4719+
* @param version1 one end of the versions range to remove
4720+
* @param version2 the other end of the versions range to remove
4721+
* @param triggeredByUser {@code true} if the API is called directly by an action from a user and checks need to
4722+
* be performed for the rollback (See: {@link #rollback(XWikiDocument, String, boolean, boolean, XWikiContext)}).
4723+
* @param context the XWiki context
4724+
* @throws XWikiException
4725+
* @since 14.10.17
4726+
* @since 15.5.3
4727+
* @since 15.8RC1
4728+
*/
4729+
@Unstable
4730+
public void deleteDocumentVersions(XWikiDocument document, String version1, String version2,
4731+
boolean triggeredByUser, XWikiContext context) throws XWikiException
47114732
{
47124733
Version v1 = new Version(version1);
47134734
Version v2 = new Version(version2);
@@ -4750,20 +4771,22 @@ public void deleteDocumentVersions(XWikiDocument document, String version1, Stri
47504771
.notify(new DocumentVersionRangeDeletingEvent(document.getDocumentReferenceWithLocale(),
47514772
lowerBound.toString(), upperBound.toString()), document, context);
47524773

4753-
// Update the archive
4754-
context.getWiki().getVersioningStore().saveXWikiDocArchive(archive, true, context);
4755-
// Make sure the cached document archive is updated too
4756-
XWikiDocument cachedDocument =
4757-
context.getWiki().getDocument(document.getDocumentReferenceWithLocale(), context);
4758-
cachedDocument.setDocumentArchive(archive);
47594774

47604775
// There are still some versions left.
47614776
// If we delete the most recent (current) version, then rollback to latest undeleted version.
4777+
// We do that right before updating the archive, in case it would cancel the action.
47624778
Version previousVersion = archive.getLatestVersion();
47634779
if (!document.getRCSVersion().equals(previousVersion)) {
4764-
context.getWiki().rollback(document, previousVersion.toString(), false, context);
4780+
context.getWiki().rollback(document, previousVersion.toString(), false, triggeredByUser, context);
47654781
}
47664782

4783+
// Update the archive
4784+
context.getWiki().getVersioningStore().saveXWikiDocArchive(archive, true, context);
4785+
// Make sure the cached document archive is updated too
4786+
XWikiDocument cachedDocument =
4787+
context.getWiki().getDocument(document.getDocumentReferenceWithLocale(), context);
4788+
cachedDocument.setDocumentArchive(archive);
4789+
47674790
// Notify after versions delete
47684791
getObservationManager()
47694792
.notify(new DocumentVersionRangeDeletedEvent(document.getDocumentReferenceWithLocale(),
@@ -7569,6 +7592,25 @@ private void restoreDeletedAttachment(XWikiAttachment rolledbackAttachment, XWik
75697592
*/
75707593
public XWikiDocument rollback(final XWikiDocument tdoc, String rev, boolean addRevision, XWikiContext xcontext)
75717594
throws XWikiException
7595+
{
7596+
return rollback(tdoc, rev, addRevision, false, xcontext);
7597+
}
7598+
7599+
/**
7600+
* @param tdoc the document to rollback
7601+
* @param rev the revision to rollback to
7602+
* @param addRevision true if a new revision should be created
7603+
* @param triggeredByUser {@code true} if this has been triggered by a user and a check needs to be performed
7604+
* @param xcontext the XWiki context
7605+
* @return the new document
7606+
* @throws XWikiException when failing to rollback the document
7607+
* @since 14.10.17
7608+
* @since 15.5.3
7609+
* @since 15.8RC1
7610+
*/
7611+
@Unstable
7612+
public XWikiDocument rollback(final XWikiDocument tdoc, String rev, boolean addRevision,
7613+
boolean triggeredByUser, XWikiContext xcontext) throws XWikiException
75727614
{
75737615
LOGGER.debug("Rolling back [{}] to version [{}]", tdoc, rev);
75747616

@@ -7647,6 +7689,10 @@ public XWikiDocument rollback(final XWikiDocument tdoc, String rev, boolean addR
76477689
message = localizePlainOrKey("core.comment.rollback", rev);
76487690
}
76497691

7692+
if (triggeredByUser) {
7693+
checkSavingDocument(xcontext.getUserReference(), document, message, false, xcontext);
7694+
}
7695+
76507696
ObservationManager om = getObservationManager();
76517697
if (om != null) {
76527698
// Notify listeners about the document that is going to be rolled back.

Diff for: xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/DeleteVersionsAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public boolean action(XWikiContext context) throws XWikiException
6565
Version v2 = versions[1];
6666

6767
if (v1 != null && v2 != null) {
68-
context.getWiki().deleteDocumentVersions(tdoc, v1.toString(), v2.toString(), context);
68+
context.getWiki().deleteDocumentVersions(tdoc, v1.toString(), v2.toString(), true, context);
6969
}
7070

7171
sendRedirect(context);

Diff for: xwiki-platform-core/xwiki-platform-oldcore/src/main/java/com/xpn/xwiki/web/RollbackAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public boolean action(XWikiContext context) throws XWikiException
7979
}
8080

8181
// Perform the rollback.
82-
xwiki.rollback(tdoc, rev, context);
82+
xwiki.rollback(tdoc, rev, true, true, context);
8383

8484
// Forward to view.
8585
String redirect = Utils.getRedirect("view", context);

Diff for: xwiki-platform-core/xwiki-platform-oldcore/src/test/java/com/xpn/xwiki/XWikiMockitoTest.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import com.xpn.xwiki.doc.XWikiDocument;
7474
import com.xpn.xwiki.internal.ReadOnlyXWikiContextProvider;
7575
import com.xpn.xwiki.internal.debug.DebugConfiguration;
76+
import com.xpn.xwiki.internal.event.UserUpdatingDocumentEvent;
7677
import com.xpn.xwiki.internal.render.groovy.ParseGroovyFromString;
7778
import com.xpn.xwiki.internal.skin.InternalSkinManager;
7879
import com.xpn.xwiki.internal.store.StoreConfiguration;
@@ -216,7 +217,7 @@ public void copyDocumentPreservesAttachmentsVersion() throws Exception
216217
}
217218

218219
/**
219-
* Verify that {@link XWiki#rollback(XWikiDocument, String, XWikiContext)} fires the right events.
220+
* Verify that {@link XWiki#rollback(XWikiDocument, String, boolean, boolean, XWikiContext)} fires the right events.
220221
*/
221222
@Test
222223
public void rollbackFiresEvents() throws Exception
@@ -236,17 +237,22 @@ public void rollbackFiresEvents() throws Exception
236237
XWikiDocument result = mock(XWikiDocument.class);
237238
when(result.getDocumentReference()).thenReturn(documentReference);
238239

240+
DocumentReference userReference = new DocumentReference("xwiki", "XWiki", "ContextUser");
241+
this.context.setUserReference(userReference);
242+
239243
String revision = "3.5";
240244
when(this.documentRevisionProvider.getRevision(document, revision)).thenReturn(result);
241245

242246
this.componentManager.registerMockComponent(ContextualLocalizationManager.class);
243247

244-
xwiki.rollback(document, revision, context);
248+
xwiki.rollback(document, revision, true, true, context);
245249

246250
verify(observationManager).notify(new DocumentRollingBackEvent(documentReference, revision), document, context);
247251
verify(observationManager).notify(new DocumentUpdatingEvent(documentReference), document, context);
248252
verify(observationManager).notify(new DocumentUpdatedEvent(documentReference), document, context);
249253
verify(observationManager).notify(new DocumentRolledBackEvent(documentReference, revision), document, context);
254+
verify(observationManager).notify(new UserUpdatingDocumentEvent(userReference, documentReference),
255+
document, context);
250256
}
251257

252258
@Test

Diff for: xwiki-platform-core/xwiki-platform-test/xwiki-platform-test-ui/src/main/java/org/xwiki/test/ui/po/HistoryPane.java

+26
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,30 @@ public ComparePage compare(String fromVersion, String toVersion)
183183
getDriver().findElementWithoutWaiting(pane, By.xpath(".//input[@accesskey = 'c']")).click();
184184
return new ComparePage();
185185
}
186+
187+
/**
188+
* @return the total number of versions contained in the history as returned by the live table
189+
* @since 14.10.17
190+
* @since 15.5.3
191+
* @since 15.8RC1
192+
*/
193+
public int getNumberOfVersions()
194+
{
195+
String xpath = ".//div[@class='paginationFilter' and following-sibling::div[@id='historycontent']]";
196+
WebElement paginationDiv = getDriver().findElementWithoutWaiting(By.xpath(xpath));
197+
return Integer.parseInt(getDriver().findElementWithoutWaiting(paginationDiv, By.className("totalResultsNo"))
198+
.getText());
199+
}
200+
201+
/**
202+
* @return {@code true} if the requested version is currently displayed in the history
203+
* @since 14.10.17
204+
* @since 15.5.3
205+
* @since 15.8RC1
206+
*/
207+
public boolean hasVersion(String version)
208+
{
209+
String xpath = String.format(".//table//tr[contains(., '%s')]", version);
210+
return getDriver().hasElementWithoutWaiting(pane, By.xpath(xpath));
211+
}
186212
}

0 commit comments

Comments
 (0)